xref: /haiku/src/bin/keymap/main.cpp (revision b55a57da7173b9af0432bd3e148d03f06161d036)
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