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