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