aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/readline.c14
-rw-r--r--include/readline.h1
-rw-r--r--sway/config.c67
3 files changed, 74 insertions, 8 deletions
diff --git a/common/readline.c b/common/readline.c
index ed5801de..abe986c4 100644
--- a/common/readline.c
+++ b/common/readline.c
@@ -48,6 +48,20 @@ char *read_line(FILE *file) {
return string;
}
+char *peek_line(FILE *file, int offset) {
+ int pos = ftell(file);
+ char *line = NULL;
+ for (int i = 0; i <= offset; i++) {
+ free(line);
+ line = read_line(file);
+ if (!line) {
+ break;
+ }
+ }
+ fseek(file, pos, SEEK_SET);
+ return line;
+}
+
char *read_line_buffer(FILE *file, char *string, size_t string_len) {
size_t length = 0;
if (!string) {
diff --git a/include/readline.h b/include/readline.h
index b3e06d4b..3f63e917 100644
--- a/include/readline.h
+++ b/include/readline.h
@@ -4,6 +4,7 @@
#include <stdio.h>
char *read_line(FILE *file);
+char *peek_line(FILE *file, int offset);
char *read_line_buffer(FILE *file, char *string, size_t string_len);
#endif
diff --git a/sway/config.c b/sway/config.c
index 26e6f3e3..edb10bd7 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -513,6 +513,49 @@ bool load_include_configs(const char *path, struct sway_config *config) {
return true;
}
+static int detect_brace_on_following_line(FILE *file, char *line,
+ int line_number) {
+ int lines = 0;
+ if (line[strlen(line) - 1] != '{' && line[strlen(line) - 1] != '}') {
+ char *peeked = NULL;
+ do {
+ wlr_log(L_DEBUG, "Peeking line %d", line_number + lines + 1);
+ free(peeked);
+ peeked = peek_line(file, lines);
+ if (peeked) {
+ peeked = strip_whitespace(peeked);
+ }
+ lines++;
+ } while (peeked && strlen(peeked) == 0);
+
+ if (peeked && strlen(peeked) == 1 && peeked[0] == '{') {
+ for (int i = 0; i < lines; i++) {
+ free(peeked);
+ peeked = read_line(file);
+ }
+ } else {
+ lines = 0;
+ }
+ free(peeked);
+ }
+ return lines;
+}
+
+static char *expand_line(char *block, char *line, bool add_brace) {
+ int size = (block ? strlen(block) + 1 : 0) + strlen(line)
+ + (add_brace ? 2 : 0) + 1;
+ char *expanded = calloc(1, size);
+ if (!expanded) {
+ wlr_log(L_ERROR, "Cannot allocate expanded line buffer");
+ return NULL;
+ }
+ strcat(expanded, block ? block : "");
+ strcat(expanded, block ? " " : "");
+ strcat(expanded, line);
+ strcat(expanded, add_brace ? " {" : "");
+ return expanded;
+}
+
bool read_config(FILE *file, struct sway_config *config) {
bool success = true;
int line_number = 0;
@@ -535,19 +578,27 @@ bool read_config(FILE *file, struct sway_config *config) {
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);
+ int brace_detected = detect_brace_on_following_line(file, line,
+ line_number);
+ if (brace_detected > 0) {
+ line_number += brace_detected;
+ wlr_log(L_DEBUG, "Detected open brace on line %d", line_number);
+ }
+ char *expanded = expand_line(block, line, brace_detected > 0);
+ if (!expanded) {
+ return false;
+ }
+ wlr_log(L_DEBUG, "Expanded line: %s", expanded);
struct cmd_results *res;
if (block && strcmp(block, "<commands>") == 0) {
// Special case
- res = config_commands_command(full);
+ res = config_commands_command(expanded);
} else {
- res = config_command(full);
+ wlr_log(L_DEBUG, "Entering c_c");
+ res = config_command(expanded);
+ wlr_log(L_DEBUG, "Exiting c_c");
}
- free(full);
+ free(expanded);
switch(res->status) {
case CMD_FAILURE:
case CMD_INVALID: