1 /* 2 * Copyright 2004-2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Jérôme Duval 7 * Axel Dörfler, axeld@pinc-software.de. 8 */ 9 10 11 #include <getopt.h> 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 16 #include <Application.h> 17 #include <FileIO.h> 18 19 #include "Keymap.h" 20 21 22 extern char *__progname; 23 static const char *sProgramName = __progname; 24 25 26 static void 27 usage() 28 { 29 printf("usage: %s {-o <output-file>} [-[l|r] | -[b|h|c|d <input-file>]]\n" 30 " -o, --output Change output file to output-file (default: " 31 "keymap.out|h).\n" 32 " -d, --dump Decompile key map to standard output (can be " 33 "redirected\n" 34 " via -o).\n" 35 " -l, --load Load key map. If no input-file is specified, it " 36 "will be\n" 37 " read from standard input.\n" 38 " -s, --load-source Load source key map from standard input when no\n" 39 " input-file is specified.\n" 40 " -r, --restore Restore system default key map.\n" 41 " -c, --compile Compile source keymap to binary.\n" 42 " -h, --header Translate source keymap to C++ header.\n", 43 sProgramName); 44 } 45 46 47 static const char* 48 keymap_error(status_t status) 49 { 50 if (status == KEYMAP_ERROR_UNKNOWN_VERSION) 51 return "Unknown keymap version"; 52 53 return strerror(status); 54 } 55 56 57 static void 58 load_keymap(Keymap& keymap, const char* name, bool source) 59 { 60 status_t status; 61 if (source) { 62 if (name != NULL) 63 status = keymap.LoadSource(name); 64 else 65 status = keymap.LoadSource(stdin); 66 } else { 67 if (name != NULL) 68 status = keymap.SetTo(name); 69 else { 70 BFileIO fileIO(stdin); 71 status = keymap.SetTo(fileIO); 72 } 73 } 74 75 if (status != B_OK) { 76 fprintf(stderr, "%s: error when loading the keymap: %s\n", sProgramName, 77 keymap_error(status)); 78 exit(1); 79 } 80 } 81 82 83 int 84 main(int argc, char** argv) 85 { 86 const char* output = NULL; 87 const char* input = NULL; 88 enum { 89 kUnspecified, 90 kLoadBinary, 91 kLoadText, 92 kSaveText, 93 kRestore, 94 kCompile, 95 kSaveHeader, 96 } mode = kUnspecified; 97 98 static struct option const kLongOptions[] = { 99 {"output", required_argument, 0, 'o'}, 100 {"dump", optional_argument, 0, 'd'}, 101 {"load", optional_argument, 0, 'l'}, 102 {"load-source", optional_argument, 0, 's'}, 103 {"restore", no_argument, 0, 'r'}, 104 {"compile", optional_argument, 0, 'c'}, 105 {"header", optional_argument, 0, 'h'}, 106 {"help", no_argument, 0, 'H'}, 107 {NULL} 108 }; 109 110 int c; 111 while ((c = getopt_long(argc, argv, "o:dblsrchH", kLongOptions, 112 NULL)) != -1) { 113 switch (c) { 114 case 0: 115 break; 116 case 'o': 117 output = optarg; 118 break; 119 case 'd': 120 mode = kSaveText; 121 input = optarg; 122 break; 123 case 'l': 124 case 'b': 125 mode = kLoadBinary; 126 input = optarg; 127 break; 128 case 's': 129 mode = kLoadText; 130 input = optarg; 131 break; 132 case 'r': 133 mode = kRestore; 134 break; 135 case 'c': 136 mode = kCompile; 137 input = optarg; 138 break; 139 case 'h': 140 mode = kSaveHeader; 141 input = optarg; 142 break; 143 144 case 'H': 145 default: 146 mode = kUnspecified; 147 break; 148 } 149 } 150 151 if (argc > optind && input == NULL) 152 input = argv[optind]; 153 154 BApplication* app = new BApplication("application/x-vnd.Haiku-keymap-cli"); 155 Keymap keymap; 156 157 switch (mode) { 158 case kUnspecified: 159 usage(); 160 break; 161 162 case kLoadBinary: 163 case kLoadText: 164 { 165 load_keymap(keymap, input, mode == kLoadText); 166 167 status_t status = keymap.SaveAsCurrent(); 168 if (status != B_OK) { 169 fprintf(stderr, "%s: error when saving as current: %s", 170 sProgramName, strerror(status)); 171 return 1; 172 } 173 174 printf("Key map loaded.\n"); 175 break; 176 } 177 178 case kSaveText: 179 { 180 if (input == NULL) { 181 status_t status = keymap.SetToCurrent(); 182 if (status != B_OK) { 183 fprintf(stderr, "%s: error while getting keymap: %s!\n", 184 sProgramName, keymap_error(status)); 185 return 1; 186 } 187 } else 188 load_keymap(keymap, input, false); 189 190 if (output != NULL) 191 keymap.SaveAsSource(output); 192 else 193 keymap.SaveAsSource(stdout); 194 break; 195 } 196 197 case kRestore: 198 keymap.RestoreSystemDefault(); 199 break; 200 201 case kCompile: 202 { 203 load_keymap(keymap, input, true); 204 205 if (output == NULL) 206 output = "keymap.out"; 207 208 status_t status = keymap.Save(output); 209 if (status != B_OK) { 210 fprintf(stderr, "%s: error saving \"%s\": %s\n", sProgramName, 211 output, strerror(status)); 212 return 1; 213 } 214 break; 215 } 216 217 case kSaveHeader: 218 { 219 load_keymap(keymap, input, true); 220 221 if (output == NULL) 222 output = "keymap.h"; 223 224 status_t status = keymap.SaveAsCppHeader(output, input); 225 if (status != B_OK) { 226 fprintf(stderr, "%s: error saving \"%s\": %s\n", sProgramName, 227 output, strerror(status)); 228 return 1; 229 } 230 break; 231 } 232 } 233 234 return 0; 235 } 236