175f15221SOliver Tappe /*
275f15221SOliver Tappe ** Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
3b6f76ebeSAugustin Cavalier ** Distributed under the terms of the MIT License.
475f15221SOliver Tappe */
575f15221SOliver Tappe
675f15221SOliver Tappe #include <cstdio>
775f15221SOliver Tappe #include <cstdlib>
875f15221SOliver Tappe #include <vector>
975f15221SOliver Tappe
1075f15221SOliver Tappe #include <Catalog.h>
1175f15221SOliver Tappe #include <Entry.h>
1275f15221SOliver Tappe #include <File.h>
1375f15221SOliver Tappe #include <String.h>
1475f15221SOliver Tappe
1575f15221SOliver Tappe #include <DefaultCatalog.h>
1675f15221SOliver Tappe #include <HashMapCatalog.h>
1775f15221SOliver Tappe #include <PlainTextCatalog.h>
1875f15221SOliver Tappe
195ac65b7fSOliver Tappe using BPrivate::CatKey;
205ac65b7fSOliver Tappe using BPrivate::DefaultCatalog;
215ac65b7fSOliver Tappe using BPrivate::HashMapCatalog;
225ac65b7fSOliver Tappe using BPrivate::PlainTextCatalog;
2375f15221SOliver Tappe using std::vector;
2475f15221SOliver Tappe
255ac65b7fSOliver Tappe
2675f15221SOliver Tappe void
usage()2775f15221SOliver Tappe usage()
2875f15221SOliver Tappe {
2975f15221SOliver Tappe fprintf(stderr,
3075f15221SOliver Tappe "usage: linkcatkeys [-v] [-t(a|f|r)] [-o <outfile>] [-l <catalogLang>]\n"
3175f15221SOliver Tappe " -s <catalogSig> <catalogFiles>\n"
3275f15221SOliver Tappe "options:\n"
3375f15221SOliver Tappe " -l <catalogLang>\tlanguage of the target-catalog (default is English)\n"
3475f15221SOliver Tappe " -o <outfile>\t\texplicitly specifies the name of the output-file\n"
3575f15221SOliver Tappe " -s <catalogSig>\tsignature of the target-catalog\n"
3675f15221SOliver Tappe " -t(a|f|r)\t\tspecifies target of resulting catalog (-tf is default)\n"
3775f15221SOliver Tappe " \t\ta => write catalog as an attribute (to output-file)\n"
3875f15221SOliver Tappe " \t\tf => write catalog into the output-file\n"
3975f15221SOliver Tappe " \t\tr => write catalog as a resource (to output-file)\n"
4075f15221SOliver Tappe " -v\t\t\tbe verbose, show summary\n");
4175f15221SOliver Tappe exit(-1);
4275f15221SOliver Tappe }
4375f15221SOliver Tappe
4475f15221SOliver Tappe
4575f15221SOliver Tappe int
main(int argc,char ** argv)4675f15221SOliver Tappe main(int argc, char **argv)
4775f15221SOliver Tappe {
4875f15221SOliver Tappe bool showSummary = false;
4975f15221SOliver Tappe bool showWarnings = false;
5075f15221SOliver Tappe vector<const char *> inputFiles;
5175f15221SOliver Tappe BString outputFile("default.catalog");
5275f15221SOliver Tappe enum TargetType {
5375f15221SOliver Tappe TARGET_ATTRIBUTE,
5475f15221SOliver Tappe TARGET_FILE,
5575f15221SOliver Tappe TARGET_RESOURCE
5675f15221SOliver Tappe };
5775f15221SOliver Tappe TargetType outputTarget = TARGET_FILE;
5875f15221SOliver Tappe const char *catalogSig = NULL;
5975f15221SOliver Tappe BString catalogLang("English");
6075f15221SOliver Tappe status_t res;
6175f15221SOliver Tappe while ((++argv)[0]) {
6275f15221SOliver Tappe if (argv[0][0] == '-' && argv[0][1] != '-') {
6375f15221SOliver Tappe char *arg = argv[0] + 1;
6475f15221SOliver Tappe char c;
6575f15221SOliver Tappe while ((c = *arg++) != '\0') {
6675f15221SOliver Tappe if (c == 's')
6775f15221SOliver Tappe catalogSig = (++argv)[0];
6875f15221SOliver Tappe else if (c == 'l')
6975f15221SOliver Tappe catalogLang = (++argv)[0];
7075f15221SOliver Tappe else if (c == 'v')
7175f15221SOliver Tappe showSummary = true;
7275f15221SOliver Tappe else if (c == 'w')
7375f15221SOliver Tappe showWarnings = true;
7475f15221SOliver Tappe else if (c == 'o') {
7575f15221SOliver Tappe outputFile = (++argv)[0];
7675f15221SOliver Tappe break;
7775f15221SOliver Tappe }
7875f15221SOliver Tappe else if (c == 't') {
7975f15221SOliver Tappe switch(*arg) {
8075f15221SOliver Tappe case 'a': outputTarget = TARGET_ATTRIBUTE; break;
8175f15221SOliver Tappe case 'f': outputTarget = TARGET_FILE; break;
8275f15221SOliver Tappe case 'r': outputTarget = TARGET_RESOURCE; break;
8375f15221SOliver Tappe default: usage();
8475f15221SOliver Tappe }
8575f15221SOliver Tappe }
8675f15221SOliver Tappe }
8775f15221SOliver Tappe } else if (!strcmp(argv[0], "--help")) {
8875f15221SOliver Tappe usage();
8975f15221SOliver Tappe } else {
9075f15221SOliver Tappe inputFiles.push_back(argv[0]);
9175f15221SOliver Tappe }
9275f15221SOliver Tappe }
9375f15221SOliver Tappe if (inputFiles.empty() || !catalogSig || !outputFile.Length())
9475f15221SOliver Tappe usage();
9575f15221SOliver Tappe
9675f15221SOliver Tappe DefaultCatalog targetCatImpl(outputFile.String(), catalogSig,
9775f15221SOliver Tappe catalogLang.String());
9875f15221SOliver Tappe if ((res = targetCatImpl.InitCheck()) != B_OK) {
9975f15221SOliver Tappe fprintf(stderr, "couldn't construct target-catalog %s - error: %s\n",
10075f15221SOliver Tappe outputFile.String(), strerror(res));
10175f15221SOliver Tappe exit(-1);
10275f15221SOliver Tappe }
10375f15221SOliver Tappe
10475f15221SOliver Tappe uint32 count = inputFiles.size();
10575f15221SOliver Tappe for (uint32 i = 0; i < count; ++i) {
10675f15221SOliver Tappe PlainTextCatalog inputCatalog(inputFiles[i], catalogSig,
10775f15221SOliver Tappe catalogLang.String());
10875f15221SOliver Tappe if ((res = inputCatalog.ReadFromFile()) != B_OK) {
10975f15221SOliver Tappe fprintf(stderr, "couldn't load source-catalog %s - error: %s\n",
11075f15221SOliver Tappe inputFiles[i], strerror(res));
11175f15221SOliver Tappe exit(-1);
11275f15221SOliver Tappe }
11375f15221SOliver Tappe
11475f15221SOliver Tappe // now walk over all entries in input-catalog and add them to
11575f15221SOliver Tappe // target catalog, unless they already exist there.
1165ac65b7fSOliver Tappe HashMapCatalog::CatWalker walker(&inputCatalog);
11775f15221SOliver Tappe while (!walker.AtEnd()) {
11875f15221SOliver Tappe const CatKey &key(walker.GetKey());
11975f15221SOliver Tappe
1202a06b5bdSOliver Tappe if (!targetCatImpl.GetString(key))
1212a06b5bdSOliver Tappe targetCatImpl.SetRawString(key, walker.GetValue());
12275f15221SOliver Tappe walker.Next();
12375f15221SOliver Tappe }
12475f15221SOliver Tappe }
12575f15221SOliver Tappe
12675f15221SOliver Tappe switch(outputTarget) {
12775f15221SOliver Tappe case TARGET_ATTRIBUTE: {
12875f15221SOliver Tappe BEntry entry(outputFile.String());
12975f15221SOliver Tappe entry_ref eref;
130*afb34591SAugustin Cavalier res = entry.GetRef(&eref);
131*afb34591SAugustin Cavalier if (res == B_OK)
1321a5c1f9eSAdrien Destugues res = targetCatImpl.WriteToAttribute(eref);
13375f15221SOliver Tappe if (res != B_OK) {
13475f15221SOliver Tappe fprintf(stderr,
13575f15221SOliver Tappe "couldn't write target-attribute to %s - error: %s\n",
13675f15221SOliver Tappe outputFile.String(), strerror(res));
13775f15221SOliver Tappe exit(-1);
13875f15221SOliver Tappe }
13975f15221SOliver Tappe break;
14075f15221SOliver Tappe }
14175f15221SOliver Tappe case TARGET_RESOURCE: {
14275f15221SOliver Tappe BEntry entry(outputFile.String());
14375f15221SOliver Tappe entry_ref eref;
144*afb34591SAugustin Cavalier res = entry.GetRef(&eref);
145*afb34591SAugustin Cavalier if (res == B_OK)
1461a5c1f9eSAdrien Destugues res = targetCatImpl.WriteToResource(eref);
14775f15221SOliver Tappe if (res != B_OK) {
14875f15221SOliver Tappe fprintf(stderr,
14975f15221SOliver Tappe "couldn't write target-resource to %s - error: %s\n",
15075f15221SOliver Tappe outputFile.String(), strerror(res));
15175f15221SOliver Tappe exit(-1);
15275f15221SOliver Tappe }
1532093ede6SAdrien Destugues break;
15475f15221SOliver Tappe }
15575f15221SOliver Tappe default: {
15675f15221SOliver Tappe res = targetCatImpl.WriteToFile(outputFile.String());
15775f15221SOliver Tappe if (res != B_OK) {
15875f15221SOliver Tappe fprintf(stderr,
15975f15221SOliver Tappe "couldn't write target-catalog to %s - error: %s\n",
16075f15221SOliver Tappe outputFile.String(), strerror(res));
16175f15221SOliver Tappe exit(-1);
16275f15221SOliver Tappe }
16375f15221SOliver Tappe }
16475f15221SOliver Tappe }
16575f15221SOliver Tappe if (showSummary) {
16675f15221SOliver Tappe int32 count = targetCatImpl.CountItems();
16775f15221SOliver Tappe if (count) {
168c090a0fdSOliver Tappe fprintf(stderr, "%d key%s found and written to %s\n",
16975f15221SOliver Tappe count, (count==1 ? "": "s"), outputFile.String());
17075f15221SOliver Tappe } else
17175f15221SOliver Tappe fprintf(stderr, "no keys found\n");
17275f15221SOliver Tappe }
17375f15221SOliver Tappe
17475f15221SOliver Tappe return res;
17575f15221SOliver Tappe }
176