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