175f15221SOliver Tappe /* 275f15221SOliver Tappe ** Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved. 375f15221SOliver Tappe ** Distributed under the terms of the OpenBeOS 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 1975f15221SOliver Tappe using std::vector; 2075f15221SOliver Tappe 2175f15221SOliver Tappe void 2275f15221SOliver Tappe usage() 2375f15221SOliver Tappe { 2475f15221SOliver Tappe fprintf(stderr, 2575f15221SOliver Tappe "usage: linkcatkeys [-v] [-t(a|f|r)] [-o <outfile>] [-l <catalogLang>]\n" 2675f15221SOliver Tappe " -s <catalogSig> <catalogFiles>\n" 2775f15221SOliver Tappe "options:\n" 2875f15221SOliver Tappe " -l <catalogLang>\tlanguage of the target-catalog (default is English)\n" 2975f15221SOliver Tappe " -o <outfile>\t\texplicitly specifies the name of the output-file\n" 3075f15221SOliver Tappe " -s <catalogSig>\tsignature of the target-catalog\n" 3175f15221SOliver Tappe " -t(a|f|r)\t\tspecifies target of resulting catalog (-tf is default)\n" 3275f15221SOliver Tappe " \t\ta => write catalog as an attribute (to output-file)\n" 3375f15221SOliver Tappe " \t\tf => write catalog into the output-file\n" 3475f15221SOliver Tappe " \t\tr => write catalog as a resource (to output-file)\n" 3575f15221SOliver Tappe " -v\t\t\tbe verbose, show summary\n"); 3675f15221SOliver Tappe exit(-1); 3775f15221SOliver Tappe } 3875f15221SOliver Tappe 3975f15221SOliver Tappe 4075f15221SOliver Tappe int 4175f15221SOliver Tappe main(int argc, char **argv) 4275f15221SOliver Tappe { 4375f15221SOliver Tappe bool showSummary = false; 4475f15221SOliver Tappe bool showWarnings = false; 4575f15221SOliver Tappe vector<const char *> inputFiles; 4675f15221SOliver Tappe BString outputFile("default.catalog"); 4775f15221SOliver Tappe enum TargetType { 4875f15221SOliver Tappe TARGET_ATTRIBUTE, 4975f15221SOliver Tappe TARGET_FILE, 5075f15221SOliver Tappe TARGET_RESOURCE 5175f15221SOliver Tappe }; 5275f15221SOliver Tappe TargetType outputTarget = TARGET_FILE; 5375f15221SOliver Tappe const char *catalogSig = NULL; 5475f15221SOliver Tappe BString catalogLang("English"); 5575f15221SOliver Tappe status_t res; 5675f15221SOliver Tappe while ((++argv)[0]) { 5775f15221SOliver Tappe if (argv[0][0] == '-' && argv[0][1] != '-') { 5875f15221SOliver Tappe char *arg = argv[0] + 1; 5975f15221SOliver Tappe char c; 6075f15221SOliver Tappe while ((c = *arg++) != '\0') { 6175f15221SOliver Tappe if (c == 's') 6275f15221SOliver Tappe catalogSig = (++argv)[0]; 6375f15221SOliver Tappe else if (c == 'l') 6475f15221SOliver Tappe catalogLang = (++argv)[0]; 6575f15221SOliver Tappe else if (c == 'v') 6675f15221SOliver Tappe showSummary = true; 6775f15221SOliver Tappe else if (c == 'w') 6875f15221SOliver Tappe showWarnings = true; 6975f15221SOliver Tappe else if (c == 'o') { 7075f15221SOliver Tappe outputFile = (++argv)[0]; 7175f15221SOliver Tappe break; 7275f15221SOliver Tappe } 7375f15221SOliver Tappe else if (c == 't') { 7475f15221SOliver Tappe switch(*arg) { 7575f15221SOliver Tappe case 'a': outputTarget = TARGET_ATTRIBUTE; break; 7675f15221SOliver Tappe case 'f': outputTarget = TARGET_FILE; break; 7775f15221SOliver Tappe case 'r': outputTarget = TARGET_RESOURCE; break; 7875f15221SOliver Tappe default: usage(); 7975f15221SOliver Tappe } 8075f15221SOliver Tappe } 8175f15221SOliver Tappe } 8275f15221SOliver Tappe } else if (!strcmp(argv[0], "--help")) { 8375f15221SOliver Tappe usage(); 8475f15221SOliver Tappe } else { 8575f15221SOliver Tappe inputFiles.push_back(argv[0]); 8675f15221SOliver Tappe } 8775f15221SOliver Tappe } 8875f15221SOliver Tappe if (inputFiles.empty() || !catalogSig || !outputFile.Length()) 8975f15221SOliver Tappe usage(); 9075f15221SOliver Tappe 9175f15221SOliver Tappe DefaultCatalog targetCatImpl(outputFile.String(), catalogSig, 9275f15221SOliver Tappe catalogLang.String()); 9375f15221SOliver Tappe if ((res = targetCatImpl.InitCheck()) != B_OK) { 9475f15221SOliver Tappe fprintf(stderr, "couldn't construct target-catalog %s - error: %s\n", 9575f15221SOliver Tappe outputFile.String(), strerror(res)); 9675f15221SOliver Tappe exit(-1); 9775f15221SOliver Tappe } 9875f15221SOliver Tappe 9975f15221SOliver Tappe uint32 count = inputFiles.size(); 10075f15221SOliver Tappe for (uint32 i = 0; i < count; ++i) { 10175f15221SOliver Tappe PlainTextCatalog inputCatalog(inputFiles[i], catalogSig, 10275f15221SOliver Tappe catalogLang.String()); 10375f15221SOliver Tappe if ((res = inputCatalog.ReadFromFile()) != B_OK) { 10475f15221SOliver Tappe fprintf(stderr, "couldn't load source-catalog %s - error: %s\n", 10575f15221SOliver Tappe inputFiles[i], strerror(res)); 10675f15221SOliver Tappe exit(-1); 10775f15221SOliver Tappe } 10875f15221SOliver Tappe 10975f15221SOliver Tappe // now walk over all entries in input-catalog and add them to 11075f15221SOliver Tappe // target catalog, unless they already exist there. 11175f15221SOliver Tappe BHashMapCatalog::CatWalker walker(&inputCatalog); 11275f15221SOliver Tappe while (!walker.AtEnd()) { 11375f15221SOliver Tappe const CatKey &key(walker.GetKey()); 11475f15221SOliver Tappe 115*2a06b5bdSOliver Tappe if (!targetCatImpl.GetString(key)) 116*2a06b5bdSOliver Tappe targetCatImpl.SetRawString(key, walker.GetValue()); 11775f15221SOliver Tappe walker.Next(); 11875f15221SOliver Tappe } 11975f15221SOliver Tappe } 12075f15221SOliver Tappe 12175f15221SOliver Tappe switch(outputTarget) { 12275f15221SOliver Tappe case TARGET_ATTRIBUTE: { 12375f15221SOliver Tappe BEntry entry(outputFile.String()); 12475f15221SOliver Tappe entry_ref eref; 12575f15221SOliver Tappe entry.GetRef(&eref); 12675f15221SOliver Tappe res = targetCatImpl.WriteToAttribute(&eref); 12775f15221SOliver Tappe if (res != B_OK) { 12875f15221SOliver Tappe fprintf(stderr, 12975f15221SOliver Tappe "couldn't write target-attribute to %s - error: %s\n", 13075f15221SOliver Tappe outputFile.String(), strerror(res)); 13175f15221SOliver Tappe exit(-1); 13275f15221SOliver Tappe } 13375f15221SOliver Tappe break; 13475f15221SOliver Tappe } 13575f15221SOliver Tappe case TARGET_RESOURCE: { 13675f15221SOliver Tappe BEntry entry(outputFile.String()); 13775f15221SOliver Tappe entry_ref eref; 13875f15221SOliver Tappe entry.GetRef(&eref); 13975f15221SOliver Tappe res = targetCatImpl.WriteToResource(&eref); 14075f15221SOliver Tappe if (res != B_OK) { 14175f15221SOliver Tappe fprintf(stderr, 14275f15221SOliver Tappe "couldn't write target-resource to %s - error: %s\n", 14375f15221SOliver Tappe outputFile.String(), strerror(res)); 14475f15221SOliver Tappe exit(-1); 14575f15221SOliver Tappe } 14675f15221SOliver Tappe } 14775f15221SOliver Tappe default: { 14875f15221SOliver Tappe res = targetCatImpl.WriteToFile(outputFile.String()); 14975f15221SOliver Tappe if (res != B_OK) { 15075f15221SOliver Tappe fprintf(stderr, 15175f15221SOliver Tappe "couldn't write target-catalog to %s - error: %s\n", 15275f15221SOliver Tappe outputFile.String(), strerror(res)); 15375f15221SOliver Tappe exit(-1); 15475f15221SOliver Tappe } 15575f15221SOliver Tappe } 15675f15221SOliver Tappe } 15775f15221SOliver Tappe if (showSummary) { 15875f15221SOliver Tappe int32 count = targetCatImpl.CountItems(); 15975f15221SOliver Tappe if (count) { 160c090a0fdSOliver Tappe fprintf(stderr, "%d key%s found and written to %s\n", 16175f15221SOliver Tappe count, (count==1 ? "": "s"), outputFile.String()); 16275f15221SOliver Tappe } else 16375f15221SOliver Tappe fprintf(stderr, "no keys found\n"); 16475f15221SOliver Tappe } 16575f15221SOliver Tappe 16675f15221SOliver Tappe return res; 16775f15221SOliver Tappe } 168