diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2018-07-28 22:56:12 -0400 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2018-08-01 22:47:54 -0400 |
commit | 6124d0f9a202ba2f39125602a35bb47d3742022b (patch) | |
tree | fbc9b0fac38809907d51bdcc7b30367c623e7b55 /swaynag/main.c | |
parent | Disable pango markup for extended message (diff) | |
download | sway-6124d0f9a202ba2f39125602a35bb47d3742022b.tar.gz sway-6124d0f9a202ba2f39125602a35bb47d3742022b.tar.zst sway-6124d0f9a202ba2f39125602a35bb47d3742022b.zip |
swaynag: split config into own file and fix optind
Diffstat (limited to 'swaynag/main.c')
-rw-r--r-- | swaynag/main.c | 296 |
1 files changed, 7 insertions, 289 deletions
diff --git a/swaynag/main.c b/swaynag/main.c index b199fac4..5c97e12a 100644 --- a/swaynag/main.c +++ b/swaynag/main.c | |||
@@ -1,12 +1,8 @@ | |||
1 | #define _XOPEN_SOURCE 700 | 1 | #define _XOPEN_SOURCE 500 |
2 | #define _POSIX_C_SOURCE 200112L | ||
3 | #include <getopt.h> | ||
4 | #include <signal.h> | 2 | #include <signal.h> |
5 | #include <stdlib.h> | ||
6 | #include <wordexp.h> | ||
7 | #include "log.h" | 3 | #include "log.h" |
8 | #include "list.h" | 4 | #include "list.h" |
9 | #include "readline.h" | 5 | #include "swaynag/config.h" |
10 | #include "swaynag/nagbar.h" | 6 | #include "swaynag/nagbar.h" |
11 | #include "swaynag/types.h" | 7 | #include "swaynag/types.h" |
12 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" | 8 | #include "wlr-layer-shell-unstable-v1-client-protocol.h" |
@@ -23,285 +19,6 @@ void sway_terminate(int code) { | |||
23 | exit(code); | 19 | exit(code); |
24 | } | 20 | } |
25 | 21 | ||
26 | static char *read_from_stdin() { | ||
27 | char *buffer = NULL; | ||
28 | while (!feof(stdin)) { | ||
29 | char *line = read_line(stdin); | ||
30 | if (!line) { | ||
31 | continue; | ||
32 | } | ||
33 | |||
34 | if (!buffer) { | ||
35 | buffer = strdup(line); | ||
36 | } else { | ||
37 | buffer = realloc(buffer, strlen(buffer) + strlen(line) + 2); | ||
38 | strcat(buffer, line); | ||
39 | strcat(buffer, "\n"); | ||
40 | } | ||
41 | |||
42 | free(line); | ||
43 | } | ||
44 | |||
45 | if (buffer && buffer[strlen(buffer) - 1] == '\n') { | ||
46 | buffer[strlen(buffer) - 1] = '\0'; | ||
47 | } | ||
48 | |||
49 | return buffer; | ||
50 | } | ||
51 | |||
52 | static int parse_options(int argc, char **argv, struct sway_nagbar *nagbar, | ||
53 | list_t *types, char **config, bool *debug) { | ||
54 | static struct option opts[] = { | ||
55 | {"button", required_argument, NULL, 'b'}, | ||
56 | {"config", required_argument, NULL, 'c'}, | ||
57 | {"debug", no_argument, NULL, 'd'}, | ||
58 | {"edge", required_argument, NULL, 'e'}, | ||
59 | {"font", required_argument, NULL, 'f'}, | ||
60 | {"help", no_argument, NULL, 'h'}, | ||
61 | {"detailed-message", no_argument, NULL, 'l'}, | ||
62 | {"detailed-button", required_argument, NULL, 'L'}, | ||
63 | {"message", required_argument, NULL, 'm'}, | ||
64 | {"output", required_argument, NULL, 'o'}, | ||
65 | {"dismiss-button", required_argument, NULL, 's'}, | ||
66 | {"type", required_argument, NULL, 't'}, | ||
67 | {"version", no_argument, NULL, 'v'}, | ||
68 | {0, 0, 0, 0} | ||
69 | }; | ||
70 | |||
71 | const char *usage = | ||
72 | "Usage: swaynag [options...]\n" | ||
73 | "\n" | ||
74 | " -b, --button <text> <action> Create a button with text that " | ||
75 | "executes action when pressed. Multiple buttons can be defined.\n" | ||
76 | " -c, --config <path> Path to config file.\n" | ||
77 | " -d, --debug Enable debugging.\n" | ||
78 | " -e, --edge top|bottom Set the edge to use.\n" | ||
79 | " -f, --font <font> Set the font to use.\n" | ||
80 | " -h, --help Show help message and quit.\n" | ||
81 | " -l, --detailed-message Read a detailed message from stdin.\n" | ||
82 | " -L, --detailed-button <text> Set the text of the detail button.\n" | ||
83 | " -m, --message <msg> Set the message text.\n" | ||
84 | " -o, --output <output> Set the output to use.\n" | ||
85 | " -s, --dismiss-button <text> Set the dismiss button text.\n" | ||
86 | " -t, --type <type> Set the message type.\n" | ||
87 | " -v, --version Show the version number and quit.\n"; | ||
88 | |||
89 | optind = 1; | ||
90 | while (1) { | ||
91 | int c = getopt_long(argc, argv, "b:c:de:f:hlL:m:o:s:t:v", opts, NULL); | ||
92 | if (c == -1) { | ||
93 | break; | ||
94 | } | ||
95 | switch (c) { | ||
96 | case 'b': // Button | ||
97 | if (nagbar) { | ||
98 | if (optind >= argc) { | ||
99 | fprintf(stderr, "Missing action for button %s\n", optarg); | ||
100 | return EXIT_FAILURE; | ||
101 | } | ||
102 | struct sway_nagbar_button *button; | ||
103 | button = calloc(sizeof(struct sway_nagbar_button), 1); | ||
104 | button->text = strdup(optarg); | ||
105 | button->type = NAGBAR_ACTION_COMMAND; | ||
106 | button->action = strdup(argv[optind]); | ||
107 | optind++; | ||
108 | list_add(nagbar->buttons, button); | ||
109 | } | ||
110 | break; | ||
111 | case 'c': // Config | ||
112 | if (config) { | ||
113 | *config = strdup(optarg); | ||
114 | } | ||
115 | break; | ||
116 | case 'd': // Debug | ||
117 | if (debug) { | ||
118 | *debug = true; | ||
119 | } | ||
120 | break; | ||
121 | case 'e': // Edge | ||
122 | if (nagbar) { | ||
123 | if (strcmp(optarg, "top") == 0) { | ||
124 | nagbar->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ||
125 | | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ||
126 | | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; | ||
127 | } else if (strcmp(optarg, "bottom") == 0) { | ||
128 | nagbar->anchors = ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ||
129 | | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ||
130 | | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT; | ||
131 | } else { | ||
132 | fprintf(stderr, "Invalid edge: %s\n", optarg); | ||
133 | return EXIT_FAILURE; | ||
134 | } | ||
135 | } | ||
136 | break; | ||
137 | case 'f': // Font | ||
138 | if (nagbar) { | ||
139 | free(nagbar->font); | ||
140 | nagbar->font = strdup(optarg); | ||
141 | } | ||
142 | break; | ||
143 | case 'l': // Detailed Message | ||
144 | if (nagbar) { | ||
145 | free(nagbar->details.message); | ||
146 | nagbar->details.message = read_from_stdin(); | ||
147 | nagbar->details.button_up.text = strdup("▲"); | ||
148 | nagbar->details.button_down.text = strdup("▼"); | ||
149 | } | ||
150 | break; | ||
151 | case 'L': // Detailed Button Text | ||
152 | if (nagbar) { | ||
153 | free(nagbar->details.button_details.text); | ||
154 | nagbar->details.button_details.text = strdup(optarg); | ||
155 | } | ||
156 | break; | ||
157 | case 'm': // Message | ||
158 | if (nagbar) { | ||
159 | free(nagbar->message); | ||
160 | nagbar->message = strdup(optarg); | ||
161 | } | ||
162 | break; | ||
163 | case 'o': // Output | ||
164 | if (nagbar) { | ||
165 | free(nagbar->output.name); | ||
166 | nagbar->output.name = strdup(optarg); | ||
167 | } | ||
168 | break; | ||
169 | case 's': // Dismiss Button Text | ||
170 | if (nagbar) { | ||
171 | struct sway_nagbar_button *button_close; | ||
172 | button_close = nagbar->buttons->items[0]; | ||
173 | free(button_close->text); | ||
174 | button_close->text = strdup(optarg); | ||
175 | } | ||
176 | break; | ||
177 | case 't': // Type | ||
178 | if (nagbar) { | ||
179 | nagbar->type = nagbar_type_get(types, optarg); | ||
180 | if (!nagbar->type) { | ||
181 | fprintf(stderr, "Unknown type %s\n", optarg); | ||
182 | return EXIT_FAILURE; | ||
183 | } | ||
184 | } | ||
185 | break; | ||
186 | case 'v': // Version | ||
187 | fprintf(stdout, "swaynag version " SWAY_VERSION "\n"); | ||
188 | return -1; | ||
189 | default: // Help or unknown flag | ||
190 | fprintf(c == 'h' ? stdout : stderr, "%s", usage); | ||
191 | return -1; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static bool file_exists(const char *path) { | ||
199 | return path && access(path, R_OK) != -1; | ||
200 | } | ||
201 | |||
202 | static char *get_config_path(void) { | ||
203 | static const char *config_paths[] = { | ||
204 | "$HOME/.swaynag/config", | ||
205 | "$XDG_CONFIG_HOME/swaynag/config", | ||
206 | SYSCONFDIR "/swaynag/config", | ||
207 | }; | ||
208 | |||
209 | if (!getenv("XDG_CONFIG_HOME")) { | ||
210 | char *home = getenv("HOME"); | ||
211 | char *config_home = malloc(strlen(home) + strlen("/.config") + 1); | ||
212 | if (!config_home) { | ||
213 | wlr_log(WLR_ERROR, "Unable to allocate $HOME/.config"); | ||
214 | } else { | ||
215 | strcpy(config_home, home); | ||
216 | strcat(config_home, "/.config"); | ||
217 | setenv("XDG_CONFIG_HOME", config_home, 1); | ||
218 | wlr_log(WLR_DEBUG, "Set XDG_CONFIG_HOME to %s", config_home); | ||
219 | free(config_home); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | wordexp_t p; | ||
224 | char *path; | ||
225 | for (size_t i = 0; i < sizeof(config_paths) / sizeof(char *); ++i) { | ||
226 | if (wordexp(config_paths[i], &p, 0) == 0) { | ||
227 | path = strdup(p.we_wordv[0]); | ||
228 | wordfree(&p); | ||
229 | if (file_exists(path)) { | ||
230 | return path; | ||
231 | } | ||
232 | free(path); | ||
233 | } | ||
234 | } | ||
235 | |||
236 | return NULL; | ||
237 | } | ||
238 | |||
239 | static int load_config(char *path, struct sway_nagbar *nagbar, list_t *types) { | ||
240 | FILE *config = fopen(path, "r"); | ||
241 | if (!config) { | ||
242 | fprintf(stderr, "Failed to read config. Running without it.\n"); | ||
243 | return 0; | ||
244 | } | ||
245 | struct sway_nagbar_type *type = NULL; | ||
246 | char *line; | ||
247 | int line_number = 0; | ||
248 | while (!feof(config)) { | ||
249 | line = read_line(config); | ||
250 | if (!line) { | ||
251 | continue; | ||
252 | } | ||
253 | |||
254 | line_number++; | ||
255 | if (line[0] == '#') { | ||
256 | free(line); | ||
257 | continue; | ||
258 | } | ||
259 | if (strlen(line) == 0) { | ||
260 | free(line); | ||
261 | continue; | ||
262 | } | ||
263 | |||
264 | if (line[0] == '[') { | ||
265 | char *close = strchr(line, ']'); | ||
266 | if (!close) { | ||
267 | free(line); | ||
268 | fclose(config); | ||
269 | fprintf(stderr, "Closing bracket not found on line %d\n", | ||
270 | line_number); | ||
271 | return 1; | ||
272 | } | ||
273 | char *name = calloc(1, close - line); | ||
274 | strncat(name, line + 1, close - line - 1); | ||
275 | type = nagbar_type_get(types, name); | ||
276 | if (!type) { | ||
277 | type = calloc(1, sizeof(struct sway_nagbar_type)); | ||
278 | type->name = strdup(name); | ||
279 | list_add(types, type); | ||
280 | } | ||
281 | free(name); | ||
282 | } else { | ||
283 | char flag[strlen(line) + 3]; | ||
284 | sprintf(flag, "--%s", line); | ||
285 | char *argv[] = {"swaynag", flag}; | ||
286 | int result; | ||
287 | if (type) { | ||
288 | result = nagbar_parse_type(2, argv, type); | ||
289 | } else { | ||
290 | result = parse_options(2, argv, nagbar, types, NULL, NULL); | ||
291 | } | ||
292 | if (result != 0) { | ||
293 | free(line); | ||
294 | fclose(config); | ||
295 | return result; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | free(line); | ||
300 | } | ||
301 | fclose(config); | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | int main(int argc, char **argv) { | 22 | int main(int argc, char **argv) { |
306 | int exit_code = EXIT_SUCCESS; | 23 | int exit_code = EXIT_SUCCESS; |
307 | 24 | ||
@@ -327,7 +44,7 @@ int main(int argc, char **argv) { | |||
327 | 44 | ||
328 | char *config_path = NULL; | 45 | char *config_path = NULL; |
329 | bool debug = false; | 46 | bool debug = false; |
330 | int launch_status = parse_options(argc, argv, NULL, NULL, | 47 | int launch_status = nagbar_parse_options(argc, argv, NULL, NULL, |
331 | &config_path, &debug); | 48 | &config_path, &debug); |
332 | if (launch_status != 0) { | 49 | if (launch_status != 0) { |
333 | exit_code = launch_status; | 50 | exit_code = launch_status; |
@@ -336,11 +53,11 @@ int main(int argc, char **argv) { | |||
336 | wlr_log_init(debug ? WLR_DEBUG : WLR_ERROR, NULL); | 53 | wlr_log_init(debug ? WLR_DEBUG : WLR_ERROR, NULL); |
337 | 54 | ||
338 | if (!config_path) { | 55 | if (!config_path) { |
339 | config_path = get_config_path(); | 56 | config_path = nagbar_get_config_path(); |
340 | } | 57 | } |
341 | if (config_path) { | 58 | if (config_path) { |
342 | wlr_log(WLR_DEBUG, "Loading config file: %s", config_path); | 59 | wlr_log(WLR_DEBUG, "Loading config file: %s", config_path); |
343 | int config_status = load_config(config_path, &nagbar, types); | 60 | int config_status = nagbar_load_config(config_path, &nagbar, types); |
344 | free(config_path); | 61 | free(config_path); |
345 | if (config_status != 0) { | 62 | if (config_status != 0) { |
346 | exit_code = config_status; | 63 | exit_code = config_status; |
@@ -349,7 +66,8 @@ int main(int argc, char **argv) { | |||
349 | } | 66 | } |
350 | 67 | ||
351 | if (argc > 1) { | 68 | if (argc > 1) { |
352 | int result = parse_options(argc, argv, &nagbar, types, NULL, NULL); | 69 | int result = nagbar_parse_options(argc, argv, &nagbar, types, |
70 | NULL, NULL); | ||
353 | if (result != 0) { | 71 | if (result != 0) { |
354 | exit_code = result; | 72 | exit_code = result; |
355 | goto cleanup; | 73 | goto cleanup; |