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