Make command block implementation generic

This commit is contained in:
Brian Ashworth 2018-05-30 13:20:02 -04:00
parent 2d480e754e
commit 7c810dc344
12 changed files with 293 additions and 410 deletions

View file

@ -59,12 +59,12 @@ static void free_mode(struct sway_mode *mode) {
}
void free_config(struct sway_config *config) {
config_clear_handler_context(config);
if (!config) {
return;
}
memset(&config->handler_context, 0, sizeof(config->handler_context));
// TODO: handle all currently unhandled lists as we add implementations
if (config->symbols) {
for (int i = 0; i < config->symbols->length; ++i) {
@ -107,7 +107,6 @@ void free_config(struct sway_config *config) {
list_free(config->command_policies);
list_free(config->feature_policies);
list_free(config->ipc_policies);
free(config->current_bar);
free(config->floating_scroll_up_cmd);
free(config->floating_scroll_down_cmd);
free(config->floating_scroll_left_cmd);
@ -514,37 +513,41 @@ bool load_include_configs(const char *path, struct sway_config *config) {
return true;
}
void config_clear_handler_context(struct sway_config *config) {
free_input_config(config->handler_context.input_config);
free_seat_config(config->handler_context.seat_config);
memset(&config->handler_context, 0, sizeof(config->handler_context));
}
bool read_config(FILE *file, struct sway_config *config) {
bool success = true;
enum cmd_status block = CMD_BLOCK_END;
int line_number = 0;
char *line;
list_t *stack = create_list();
while (!feof(file)) {
char *block = stack->length ? stack->items[0] : NULL;
line = read_line(file);
if (!line) {
continue;
}
line_number++;
wlr_log(L_DEBUG, "Read line %d: %s", line_number, line);
line = strip_whitespace(line);
if (line[0] == '#') {
free(line);
continue;
}
struct cmd_results *res;
if (block == CMD_BLOCK_COMMANDS) {
// Special case
res = config_commands_command(line);
} else {
res = config_command(line, block);
if (strlen(line) == 0) {
free(line);
continue;
}
char *full = calloc(strlen(block ? block : "") + strlen(line) + 2, 1);
strcat(full, block ? block : "");
strcat(full, block ? " " : "");
strcat(full, line);
wlr_log(L_DEBUG, "Expanded line: %s", full);
struct cmd_results *res;
if (block && strcmp(block, "<commands>") == 0) {
// Special case
res = config_commands_command(full);
} else {
res = config_command(full);
}
free(full);
switch(res->status) {
case CMD_FAILURE:
case CMD_INVALID:
@ -558,126 +561,41 @@ bool read_config(FILE *file, struct sway_config *config) {
list_add(config->cmd_queue, strdup(line));
break;
case CMD_BLOCK_MODE:
if (block == CMD_BLOCK_END) {
block = CMD_BLOCK_MODE;
} else {
wlr_log(L_ERROR, "Invalid block '%s'", line);
}
break;
case CMD_BLOCK_INPUT:
if (block == CMD_BLOCK_END) {
block = CMD_BLOCK_INPUT;
} else {
wlr_log(L_ERROR, "Invalid block '%s'", line);
}
break;
case CMD_BLOCK_SEAT:
if (block == CMD_BLOCK_END) {
block = CMD_BLOCK_SEAT;
} else {
wlr_log(L_ERROR, "Invalid block '%s'", line);
}
break;
case CMD_BLOCK_BAR:
if (block == CMD_BLOCK_END) {
block = CMD_BLOCK_BAR;
} else {
wlr_log(L_ERROR, "Invalid block '%s'", line);
}
break;
case CMD_BLOCK_BAR_COLORS:
if (block == CMD_BLOCK_BAR) {
block = CMD_BLOCK_BAR_COLORS;
} else {
wlr_log(L_ERROR, "Invalid block '%s'", line);
}
break;
case CMD_BLOCK_COMMANDS:
if (block == CMD_BLOCK_END) {
block = CMD_BLOCK_COMMANDS;
} else {
wlr_log(L_ERROR, "Invalid block '%s'", line);
}
wlr_log(L_DEBUG, "Entering commands block");
list_insert(stack, 0, "<commands>");
break;
case CMD_BLOCK_IPC:
if (block == CMD_BLOCK_END) {
block = CMD_BLOCK_IPC;
} else {
wlr_log(L_ERROR, "Invalid block '%s'", line);
}
break;
case CMD_BLOCK_IPC_EVENTS:
if (block == CMD_BLOCK_IPC) {
block = CMD_BLOCK_IPC_EVENTS;
} else {
wlr_log(L_ERROR, "Invalid block '%s'", line);
case CMD_BLOCK:
wlr_log(L_DEBUG, "Entering block '%s'", res->input);
list_insert(stack, 0, strdup(res->input));
if (strcmp(res->input, "bar") == 0) {
config->current_bar = NULL;
}
break;
case CMD_BLOCK_END:
switch(block) {
case CMD_BLOCK_MODE:
wlr_log(L_DEBUG, "End of mode block");
config->current_mode = config->modes->items[0];
block = CMD_BLOCK_END;
if (!block) {
wlr_log(L_DEBUG, "Unmatched '}' on line %i", line_number);
success = false;
break;
case CMD_BLOCK_INPUT:
wlr_log(L_DEBUG, "End of input block");
block = CMD_BLOCK_END;
break;
case CMD_BLOCK_SEAT:
wlr_log(L_DEBUG, "End of seat block");
block = CMD_BLOCK_END;
break;
case CMD_BLOCK_BAR:
wlr_log(L_DEBUG, "End of bar block");
config->current_bar = NULL;
block = CMD_BLOCK_END;
break;
case CMD_BLOCK_BAR_COLORS:
wlr_log(L_DEBUG, "End of bar colors block");
block = CMD_BLOCK_BAR;
break;
case CMD_BLOCK_COMMANDS:
wlr_log(L_DEBUG, "End of commands block");
block = CMD_BLOCK_END;
break;
case CMD_BLOCK_IPC:
wlr_log(L_DEBUG, "End of IPC block");
block = CMD_BLOCK_END;
break;
case CMD_BLOCK_IPC_EVENTS:
wlr_log(L_DEBUG, "End of IPC events block");
block = CMD_BLOCK_IPC;
break;
case CMD_BLOCK_END:
wlr_log(L_ERROR, "Unmatched }");
break;
default:;
}
config_clear_handler_context(config);
wlr_log(L_DEBUG, "Exiting block '%s'", block);
list_del(stack, 0);
free(block);
if (strcmp(block, "bar") == 0) {
config->current_bar = NULL;
}
memset(&config->handler_context, 0,
sizeof(config->handler_context));
default:;
}
free(line);
free_cmd_results(res);
}
list_foreach(stack, free);
list_free(stack);
return success;
}