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
usage()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*
keymap_error(status_t status)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
load_keymap(Keymap & keymap,const char * name,bool source)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
main(int argc,char ** argv)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("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