From fc1477dfb52e0af0fbcb960c07d4615a757b8640 Mon Sep 17 00:00:00 2001 From: hwangcc23 Date: Tue, 14 Jul 2015 23:38:45 +0800 Subject: [PATCH] Support config file line continuation 1. Allow to use the line continuation, which is indicated by \ before the new line character, in config files. 2. Add a new testcase "247-config-line-continuation.t" for a). testing line continuation b). making sure string escaping still works c). testing line continuations within a string b). testing line continuations with too many lines --- docs/userguide | 13 ++ src/config_parser.c | 27 +-- testcases/t/247-config-line-continuation.t | 201 +++++++++++++++++++++ 3 files changed, 229 insertions(+), 12 deletions(-) create mode 100644 testcases/t/247-config-line-continuation.t diff --git a/docs/userguide b/docs/userguide index 65d82d97..9a41a490 100644 --- a/docs/userguide +++ b/docs/userguide @@ -1078,6 +1078,19 @@ show_marks yes|no show_marks yes -------------- +[[line_continuation]] + +=== Line continuation + +Config files support line continuation, which is indicated by \ before the +new line character. + +*Examples*: +------------------- +bindsym Mod1+f \ +fullscreen toggle +------------------- + == Configuring i3bar The bar at the bottom of your monitor is drawn by a separate process called diff --git a/src/config_parser.c b/src/config_parser.c index a9baef27..3fd4e09a 100644 --- a/src/config_parser.c +++ b/src/config_parser.c @@ -837,11 +837,11 @@ static char *migrate_config(char *input, off_t size) { */ bool parse_file(const char *f, bool use_nagbar) { SLIST_HEAD(variables_head, Variable) variables = SLIST_HEAD_INITIALIZER(&variables); - int fd, ret, read_bytes = 0; + int fd; struct stat stbuf; char *buf; FILE *fstr; - char buffer[1026], key[512], value[512]; + char buffer[4096], key[512], value[512], *continuation = NULL; if ((fd = open(f, O_RDONLY)) == -1) die("Could not open configuration file: %s\n", strerror(errno)); @@ -850,27 +850,30 @@ bool parse_file(const char *f, bool use_nagbar) { die("Could not fstat file: %s\n", strerror(errno)); buf = scalloc((stbuf.st_size + 1) * sizeof(char)); - while (read_bytes < stbuf.st_size) { - if ((ret = read(fd, buf + read_bytes, (stbuf.st_size - read_bytes))) < 0) - die("Could not read(): %s\n", strerror(errno)); - read_bytes += ret; - } - - if (lseek(fd, 0, SEEK_SET) == (off_t)-1) - die("Could not lseek: %s\n", strerror(errno)); if ((fstr = fdopen(fd, "r")) == NULL) die("Could not fdopen: %s\n", strerror(errno)); while (!feof(fstr)) { - if (fgets(buffer, 1024, fstr) == NULL) { + if (!continuation) + continuation = buffer; + if (fgets(continuation, sizeof(buffer) - (continuation - buffer), fstr) == NULL) { if (feof(fstr)) break; die("Could not read configuration file\n"); } + if (buffer[strlen(buffer) - 1] != '\n') { + ELOG("Use continuation with too many lines\n"); + } + continuation = strstr(buffer, "\\\n"); + if (continuation) { + continue; + } + + strncpy(buf + strlen(buf), buffer, strlen(buffer) + 1); /* sscanf implicitly strips whitespace. Also, we skip comments and empty lines. */ - if (sscanf(buffer, "%s %[^\n]", key, value) < 1 || + if (sscanf(buffer, "%511s %511[^\n]", key, value) < 1 || key[0] == '#' || strlen(key) < 3) continue; diff --git a/testcases/t/247-config-line-continuation.t b/testcases/t/247-config-line-continuation.t new file mode 100644 index 00000000..0396d872 --- /dev/null +++ b/testcases/t/247-config-line-continuation.t @@ -0,0 +1,201 @@ +#!perl +# vim:ts=4:sw=4:expandtab +# +# Please read the following documents before working on tests: +# • http://build.i3wm.org/docs/testsuite.html +# (or docs/testsuite) +# +# • http://build.i3wm.org/docs/lib-i3test.html +# (alternatively: perldoc ./testcases/lib/i3test.pm) +# +# • http://build.i3wm.org/docs/ipc.html +# (or docs/ipc) +# +# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf +# (unless you are already familiar with Perl) +# +# Checks that the line continuation are parsed correctly +# + +use i3test i3_autostart => 0; + +# starts i3 with the given config, opens a window, returns its border style +sub launch_get_border { + my ($config) = @_; + + my $pid = launch_with_config($config); + + my $i3 = i3(get_socket_path(0)); + my $tmp = fresh_workspace; + + my $window = open_window(name => '"special title"'); + + my @content = @{get_ws_content($tmp)}; + cmp_ok(@content, '==', 1, 'one node on this workspace now'); + my $border = $content[0]->{border}; + + exit_gracefully($pid); + + return $border; +} + +##################################################################### +# test string escaping +##################################################################### + +my $config = <<'EOT'; +# i3 config file (v4) +font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 + +set $vartest \"special title\" +for_window [title="$vartest"] border none +EOT + +is(launch_get_border($config), 'none', 'no border'); + +##################################################################### +# test the line continuation +##################################################################### + +$config = <<'EOT'; +# i3 config file (v4) +font \ +-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 + +# Use line contiuation with too many lines (>4096 characters). +# This config is invalid. Use it to ensure no buffer overflow. +bindsym Mod1+b \ +0001-This is a very very very very very very very very very very very very very very very very very long cmd \ +0002-This is a very very very very very very very very very very very very very very very very very long cmd \ +0003-This is a very very very very very very very very very very very very very very very very very long cmd \ +0004-This is a very very very very very very very very very very very very very very very very very long cmd \ +0005-This is a very very very very very very very very very very very very very very very very very long cmd \ +0006-This is a very very very very very very very very very very very very very very very very very long cmd \ +0007-This is a very very very very very very very very very very very very very very very very very long cmd \ +0008-This is a very very very very very very very very very very very very very very very very very long cmd \ +0009-This is a very very very very very very very very very very very very very very very very very long cmd \ +0010-This is a very very very very very very very very very very very very very very very very very long cmd \ +0011-This is a very very very very very very very very very very very very very very very very very long cmd \ +0012-This is a very very very very very very very very very very very very very very very very very long cmd \ +0013-This is a very very very very very very very very very very very very very very very very very long cmd \ +0014-This is a very very very very very very very very very very very very very very very very very long cmd \ +0015-This is a very very very very very very very very very very very very very very very very very long cmd \ +0016-This is a very very very very very very very very very very very very very very very very very long cmd \ +0017-This is a very very very very very very very very very very very very very very very very very long cmd \ +0018-This is a very very very very very very very very very very very very very very very very very long cmd \ +0019-This is a very very very very very very very very very very very very very very very very very long cmd \ +0020-This is a very very very very very very very very very very very very very very very very very long cmd \ +0021-This is a very very very very very very very very very very very very very very very very very long cmd \ +0022-This is a very very very very very very very very very very very very very very very very very long cmd \ +0023-This is a very very very very very very very very very very very very very very very very very long cmd \ +0024-This is a very very very very very very very very very very very very very very very very very long cmd \ +0025-This is a very very very very very very very very very very very very very very very very very long cmd \ +0026-This is a very very very very very very very very very very very very very very very very very long cmd \ +0027-This is a very very very very very very very very very very very very very very very very very long cmd \ +0028-This is a very very very very very very very very very very very very very very very very very long cmd \ +0029-This is a very very very very very very very very very very very very very very very very very long cmd \ +0030-This is a very very very very very very very very very very very very very very very very very long cmd \ +0031-This is a very very very very very very very very very very very very very very very very very long cmd \ +0032-This is a very very very very very very very very very very very very very very very very very long cmd \ +0033-This is a very very very very very very very very very very very very very very very very very long cmd \ +0034-This is a very very very very very very very very very very very very very very very very very long cmd \ +0035-This is a very very very very very very very very very very very very very very very very very long cmd \ +0036-This is a very very very very very very very very very very very very very very very very very long cmd \ +0037-This is a very very very very very very very very very very very very very very very very very long cmd \ +0038-This is a very very very very very very very very very very very very very very very very very long cmd \ +0039-This is a very very very very very very very very very very very very very very very very very long cmd \ +0040-This is a very very very very very very very very very very very very very very very very very long cmd \ +0041-This is a very very very very very very very very very very very very very very very very very long cmd \ +0042-This is a very very very very very very very very very very very very very very very very very long cmd \ +0043-This is a very very very very very very very very very very very very very very very very very long cmd \ +0044-This is a very very very very very very very very very very very very very very very very very long cmd \ +0045-This is a very very very very very very very very very very very very very very very very very long cmd \ +0046-This is a very very very very very very very very very very very very very very very very very long cmd \ +0047-This is a very very very very very very very very very very very very very very very very very long cmd \ +0048-This is a very very very very very very very very very very very very very very very very very long cmd \ +0049-This is a very very very very very very very very very very very very very very very very very long cmd \ +0050-This is a very very very very very very very very very very very very very very very very very long cmd \ +0051-This is a very very very very very very very very very very very very very very very very very long cmd \ +0052-This is a very very very very very very very very very very very very very very very very very long cmd \ +0053-This is a very very very very very very very very very very very very very very very very very long cmd \ +0054-This is a very very very very very very very very very very very very very very very very very long cmd \ +0055-This is a very very very very very very very very very very very very very very very very very long cmd \ +0056-This is a very very very very very very very very very very very very very very very very very long cmd \ +0057-This is a very very very very very very very very very very very very very very very very very long cmd \ +0058-This is a very very very very very very very very very very very very very very very very very long cmd \ +0059-This is a very very very very very very very very very very very very very very very very very long cmd \ +0060-This is a very very very very very very very very very very very very very very very very very long cmd \ +0061-This is a very very very very very very very very very very very very very very very very very long cmd \ +0062-This is a very very very very very very very very very very very very very very very very very long cmd \ +0063-This is a very very very very very very very very very very very very very very very very very long cmd \ +0064-This is a very very very very very very very very very very very very very very very very very long cmd \ +0065-This is a very very very very very very very very very very very very very very very very very long cmd \ +0066-This is a very very very very very very very very very very very very very very very very very long cmd \ +0067-This is a very very very very very very very very very very very very very very very very very long cmd \ +0068-This is a very very very very very very very very very very very very very very very very very long cmd \ +0069-This is a very very very very very very very very very very very very very very very very very long cmd \ +0070-This is a very very very very very very very very very very very very very very very very very long cmd \ +0071-This is a very very very very very very very very very very very very very very very very very long cmd \ +0072-This is a very very very very very very very very very very very very very very very very very long cmd \ +0073-This is a very very very very very very very very very very very very very very very very very long cmd \ +0074-This is a very very very very very very very very very very very very very very very very very long cmd \ +0075-This is a very very very very very very very very very very very very very very very very very long cmd \ +0076-This is a very very very very very very very very very very very very very very very very very long cmd \ +0077-This is a very very very very very very very very very very very very very very very very very long cmd \ +0078-This is a very very very very very very very very very very very very very very very very very long cmd \ +0079-This is a very very very very very very very very very very very very very very very very very long cmd \ +0080-This is a very very very very very very very very very very very very very very very very very long cmd \ +0081-This is a very very very very very very very very very very very very very very very very very long cmd \ +0082-This is a very very very very very very very very very very very very very very very very very long cmd \ +0083-This is a very very very very very very very very very very very very very very very very very long cmd \ +0084-This is a very very very very very very very very very very very very very very very very very long cmd \ +0085-This is a very very very very very very very very very very very very very very very very very long cmd \ +0086-This is a very very very very very very very very very very very very very very very very very long cmd \ +0087-This is a very very very very very very very very very very very very very very very very very long cmd \ +0088-This is a very very very very very very very very very very very very very very very very very long cmd \ +0089-This is a very very very very very very very very very very very very very very very very very long cmd \ +0090-This is a very very very very very very very very very very very very very very very very very long cmd \ +0091-This is a very very very very very very very very very very very very very very very very very long cmd \ +0092-This is a very very very very very very very very very very very very very very very very very long cmd \ +0093-This is a very very very very very very very very very very very very very very very very very long cmd \ +0094-This is a very very very very very very very very very very very very very very very very very long cmd \ +0095-This is a very very very very very very very very very very very very very very very very very long cmd \ +0096-This is a very very very very very very very very very very very very very very very very very long cmd \ +0097-This is a very very very very very very very very very very very very very very very very very long cmd \ +0098-This is a very very very very very very very very very very very very very very very very very long cmd \ +0099-This is a very very very very very very very very very very very very very very very very very long cmd + +# Use line continuation for variables +set \ +$vartest \ +\"special title\" + +# Use line continuation for commands +for_window \ +[title="$vartest"] \ +border \ +none + +EOT + +is(launch_get_border($config), 'none', 'no border'); + +##################################################################### +# test the line continuation within a string +##################################################################### + +$config = <<'EOT'; +# i3 config file (v4) +font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 + +set \ +$vartest \ +\"special \ +title\" +for_window [title="$vartest"] border none +EOT + +is(launch_get_border($config), 'none', 'no border'); + + +done_testing;