⛏️ index : haiku.git

/*
** Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the MIT License.
*/

#include <cstdio>
#include <cstdlib>
#include <vector>

#include <Catalog.h>
#include <Entry.h>
#include <File.h>
#include <String.h>

#include <DefaultCatalog.h>
#include <HashMapCatalog.h>
#include <PlainTextCatalog.h>

using BPrivate::CatKey;
using BPrivate::DefaultCatalog;
using BPrivate::HashMapCatalog;
using BPrivate::PlainTextCatalog;
using std::vector;


void
usage()
{
	fprintf(stderr,
		"usage: linkcatkeys [-v] [-t(a|f|r)] [-o <outfile>] [-l <catalogLang>]\n"
		"                   -s <catalogSig> <catalogFiles>\n"
		"options:\n"
		"  -l <catalogLang>\tlanguage of the target-catalog (default is English)\n"
		"  -o <outfile>\t\texplicitly specifies the name of the output-file\n"
		"  -s <catalogSig>\tsignature of the target-catalog\n"
		"  -t(a|f|r)\t\tspecifies target of resulting catalog (-tf is default)\n"
		"           \t\ta => write catalog as an attribute (to output-file)\n"
		"           \t\tf => write catalog into the output-file\n"
		"           \t\tr => write catalog as a resource (to output-file)\n"
		"  -v\t\t\tbe verbose, show summary\n");
	exit(-1);
}


int
main(int argc, char **argv)
{
	bool showSummary = false;
	bool showWarnings = false;
	vector<const char *> inputFiles;
	BString outputFile("default.catalog");
	enum TargetType {
		TARGET_ATTRIBUTE,
		TARGET_FILE,
		TARGET_RESOURCE
	};
	TargetType outputTarget = TARGET_FILE;
	const char *catalogSig = NULL;
	BString catalogLang("English");
	status_t res;
	while ((++argv)[0]) {
		if (argv[0][0] == '-' && argv[0][1] != '-') {
			char *arg = argv[0] + 1;
			char c;
			while ((c = *arg++) != '\0') {
				if (c == 's')
					catalogSig = (++argv)[0];
				else if (c == 'l')
					catalogLang = (++argv)[0];
				else if (c == 'v')
					showSummary = true;
				else if (c == 'w')
					showWarnings = true;
				else if (c == 'o') {
					outputFile = (++argv)[0];
					break;
				}
				else if (c == 't') {
					switch(*arg) {
						case 'a': outputTarget = TARGET_ATTRIBUTE; break;
						case 'f': outputTarget = TARGET_FILE; break;
						case 'r': outputTarget = TARGET_RESOURCE; break;
						default: usage();
					}
				}
			}
		} else if (!strcmp(argv[0], "--help")) {
			usage();
		} else {
			inputFiles.push_back(argv[0]);
		}
	}
	if (inputFiles.empty() || !catalogSig || !outputFile.Length())
		usage();

	DefaultCatalog targetCatImpl(outputFile.String(), catalogSig,
		catalogLang.String());
	if ((res = targetCatImpl.InitCheck()) != B_OK) {
		fprintf(stderr, "couldn't construct target-catalog %s - error: %s\n",
			outputFile.String(), strerror(res));
		exit(-1);
	}

	uint32 count = inputFiles.size();
	for (uint32 i = 0; i < count; ++i) {
		PlainTextCatalog inputCatalog(inputFiles[i], catalogSig,
			catalogLang.String());
		if ((res = inputCatalog.ReadFromFile()) != B_OK) {
			fprintf(stderr, "couldn't load source-catalog %s - error: %s\n",
				inputFiles[i], strerror(res));
			exit(-1);
		}

		// now walk over all entries in input-catalog and add them to
		// target catalog, unless they already exist there.
		HashMapCatalog::CatWalker walker(&inputCatalog);
		while (!walker.AtEnd()) {
			const CatKey &key(walker.GetKey());

			if (!targetCatImpl.GetString(key))
				targetCatImpl.SetRawString(key, walker.GetValue());
			walker.Next();
		}
	}

	switch(outputTarget) {
		case TARGET_ATTRIBUTE: {
			BEntry entry(outputFile.String());
			entry_ref eref;
			res = entry.GetRef(&eref);
			if (res == B_OK)
				res = targetCatImpl.WriteToAttribute(eref);
			if (res != B_OK) {
				fprintf(stderr,
					"couldn't write target-attribute to %s - error: %s\n",
					outputFile.String(), strerror(res));
				exit(-1);
			}
			break;
		}
		case TARGET_RESOURCE: {
			BEntry entry(outputFile.String());
			entry_ref eref;
			res = entry.GetRef(&eref);
			if (res == B_OK)
				res = targetCatImpl.WriteToResource(eref);
			if (res != B_OK) {
				fprintf(stderr,
					"couldn't write target-resource to %s - error: %s\n",
					outputFile.String(), strerror(res));
				exit(-1);
			}
			break;
		}
		default: {
			res = targetCatImpl.WriteToFile(outputFile.String());
			if (res != B_OK) {
				fprintf(stderr,
					"couldn't write target-catalog to %s - error: %s\n",
					outputFile.String(), strerror(res));
				exit(-1);
			}
		}
	}
	if (showSummary) {
		int32 count = targetCatImpl.CountItems();
		if (count) {
			fprintf(stderr, "%d key%s found and written to %s\n",
				count, (count==1 ? "": "s"), outputFile.String());
		} else
			fprintf(stderr, "no keys found\n");
	}

	return res;
}