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 <Entry.h> 11 #include <File.h> 12 #include <String.h> 13 14 #include <EditableCatalog.h> 15 #include <DefaultCatalog.h> 16 #include <HashMapCatalog.h> 17 18 19 using BPrivate::CatKey; 20 using BPrivate::DefaultCatalog; 21 using BPrivate::EditableCatalog; 22 using BPrivate::HashMapCatalog; 23 using std::vector; 24 25 26 void 27 usage() 28 { 29 fprintf(stderr, 30 "usage: linkcatkeys [-v] [-t(a|f|r)] [-o <outfile>] [-l <catalogLang>]\n" 31 " -s <catalogSig> <catalogFiles>\n" 32 "options:\n" 33 " -l <catalogLang>\tlanguage of the target-catalog (default is English)\n" 34 " -o <outfile>\t\texplicitly specifies the name of the output-file\n" 35 " -s <catalogSig>\tsignature of the target-catalog\n" 36 " -t(a|f|r)\t\tspecifies target of resulting catalog (-tf is default)\n" 37 " \t\ta => write catalog as an attribute (to output-file)\n" 38 " \t\tf => write catalog into the output-file\n" 39 " \t\tr => write catalog as a resource (to output-file)\n" 40 " -v\t\t\tbe verbose, show summary\n"); 41 exit(-1); 42 } 43 44 45 int 46 main(int argc, char **argv) 47 { 48 bool showSummary = false; 49 bool showWarnings = false; 50 vector<const char *> inputFiles; 51 BString outputFile("default.catalog"); 52 enum TargetType { 53 TARGET_ATTRIBUTE, 54 TARGET_FILE, 55 TARGET_RESOURCE 56 }; 57 TargetType outputTarget = TARGET_FILE; 58 const char *catalogSig = NULL; 59 BString catalogLang("English"); 60 status_t res; 61 while ((++argv)[0]) { 62 if (argv[0][0] == '-' && argv[0][1] != '-') { 63 char *arg = argv[0] + 1; 64 char c; 65 while ((c = *arg++) != '\0') { 66 if (c == 's') 67 catalogSig = (++argv)[0]; 68 else if (c == 'l') 69 catalogLang = (++argv)[0]; 70 else if (c == 'v') 71 showSummary = true; 72 else if (c == 'w') 73 showWarnings = true; 74 else if (c == 'o') { 75 outputFile = (++argv)[0]; 76 break; 77 } 78 else if (c == 't') { 79 switch(*arg) { 80 case 'a': outputTarget = TARGET_ATTRIBUTE; break; 81 case 'f': outputTarget = TARGET_FILE; break; 82 case 'r': outputTarget = TARGET_RESOURCE; break; 83 default: usage(); 84 } 85 } 86 } 87 } else if (!strcmp(argv[0], "--help")) { 88 usage(); 89 } else { 90 inputFiles.push_back(argv[0]); 91 } 92 } 93 if (inputFiles.empty() || !catalogSig || !outputFile.Length()) 94 usage(); 95 96 EditableCatalog targetCatalog("Default", catalogSig, catalogLang.String()); 97 if ((res = targetCatalog.InitCheck()) != B_OK) { 98 fprintf(stderr, "couldn't construct target-catalog %s - error: %s\n", 99 outputFile.String(), strerror(res)); 100 exit(-1); 101 } 102 DefaultCatalog* targetCatImpl 103 = dynamic_cast<DefaultCatalog*>(targetCatalog.CatalogData()); 104 if (!targetCatImpl) { 105 fprintf(stderr, "couldn't access impl of target-catalog %s\n", 106 outputFile.String()); 107 exit(-1); 108 } 109 110 uint32 count = inputFiles.size(); 111 for( uint32 i=0; i<count; ++i) { 112 EditableCatalog inputCatalog("plaintext", catalogSig, "native"); 113 if ((res = inputCatalog.ReadFromFile(inputFiles[i])) != B_OK) { 114 fprintf(stderr, "couldn't load source-catalog %s - error: %s\n", 115 inputFiles[i], strerror(res)); 116 exit(-1); 117 } 118 HashMapCatalog* inputCatImpl 119 = dynamic_cast<HashMapCatalog*>(inputCatalog.CatalogData()); 120 if (!inputCatImpl) { 121 fprintf(stderr, "couldn't access impl of input-catalog %s\n", 122 inputFiles[i]); 123 exit(-1); 124 } 125 126 // now walk over all entries in input-catalog and add them to 127 // target catalog, unless they already exist there. 128 HashMapCatalog::CatWalker walker(inputCatImpl); 129 while (!walker.AtEnd()) { 130 const CatKey &plainTextKey(walker.GetKey()); 131 BString keyString, keyComment, keyContext; 132 plainTextKey.GetStringParts(&keyString,&keyComment,&keyContext); 133 const CatKey fixedCatKey(keyString.String(), keyComment.String(), 134 keyContext.String()); 135 136 if (!targetCatImpl->GetString(fixedCatKey)) 137 targetCatImpl->SetRawString(fixedCatKey, walker.GetValue()); 138 walker.Next(); 139 } 140 } 141 142 switch(outputTarget) { 143 case TARGET_ATTRIBUTE: { 144 BEntry entry(outputFile.String()); 145 entry_ref eref; 146 entry.GetRef(&eref); 147 res = targetCatalog.WriteToAttribute(eref); 148 if (res != B_OK) { 149 fprintf(stderr, 150 "couldn't write target-attribute to %s - error: %s\n", 151 outputFile.String(), strerror(res)); 152 exit(-1); 153 } 154 break; 155 } 156 case TARGET_RESOURCE: { 157 BEntry entry(outputFile.String()); 158 entry_ref eref; 159 entry.GetRef(&eref); 160 res = targetCatalog.WriteToResource(eref); 161 if (res != B_OK) { 162 fprintf(stderr, 163 "couldn't write target-resource to %s - error: %s\n", 164 outputFile.String(), strerror(res)); 165 exit(-1); 166 } 167 break; 168 } 169 default: { 170 res = targetCatalog.WriteToFile(outputFile.String()); 171 if (res != B_OK) { 172 fprintf(stderr, 173 "couldn't write target-catalog to %s - error: %s\n", 174 outputFile.String(), strerror(res)); 175 exit(-1); 176 } 177 break; 178 } 179 } 180 if (showSummary) { 181 int32 count = targetCatalog.CountItems(); 182 if (count) { 183 fprintf(stderr, "%ld key%s found and written to %s\n", 184 count, (count==1 ? "": "s"), outputFile.String()); 185 } else 186 fprintf(stderr, "no keys found\n"); 187 } 188 189 return res; 190 } 191