From: kay.sievers@vrfy.org Date: Mon, 20 Dec 2004 06:38:33 +0000 (+0100) Subject: [PATCH] allow multiline rules by backslash at the end of the line X-Git-Tag: 051~34 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9f8dfa19cfd2b502bf794f39a421cbb7c4cc0404;p=systemd [PATCH] allow multiline rules by backslash at the end of the line On Sun, 2004-12-19 at 18:31 +0100, Marco d'Itri wrote: > > On Dec 19, Kay Sievers wrote: > > > (Feature request: would it be possible to extend the rules files parser > > to support continuation lines? I'd like it to consider lines starting > > with white space as part of the previous line.) > > How about the usual backslash at the end of the line. Here is a simple > patch. --- diff --git a/namedev_parse.c b/namedev_parse.c index 7190cdd1..3b14a6a5 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -126,14 +126,15 @@ static int namedev_parse(const char *filename, void *data) cur = 0; lineno = 0; while (cur < bufsize) { + int i, j; + count = buf_get_line(buf, bufsize, cur); bufline = &buf[cur]; cur += count+1; lineno++; if (count >= LINE_SIZE) { - info("line too long, rule skipped %s, line %d", - filename, lineno); + info("line too long, rule skipped %s, line %d", filename, lineno); continue; } @@ -149,8 +150,14 @@ static int namedev_parse(const char *filename, void *data) if (bufline[0] == COMMENT_CHARACTER) continue; - strncpy(line, bufline, count); - line[count] = '\0'; + /* skip backslash and newline from multi line rules */ + for (i = j = 0; i < count; i++) { + if (bufline[i] == '\\' || bufline[i] == '\n') + continue; + + line[j++] = bufline[i]; + } + line[j] = '\0'; dbg_parse("read '%s'", line); /* get all known keys */ diff --git a/test/udev-test.pl b/test/udev-test.pl index 9a581ce5..53eee354 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -187,6 +187,36 @@ EOF KERNEL="ttyUSB0", NAME="visor" +EOF + }, + { + desc => "Handle backslashed multi lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor" , + conf => < "Handle stupid backslashed multi lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor" , + conf => < #include #include +#include #include #include #include @@ -111,6 +112,41 @@ int create_path(const char *path) return mkdir(p, 0755); } +int parse_get_pair(char **orig_string, char **left, char **right) +{ + char *temp; + char *string = *orig_string; + + if (!string) + return -ENODEV; + + /* eat any whitespace */ + while (isspace(*string) || *string == ',') + ++string; + + /* split based on '=' */ + temp = strsep(&string, "="); + *left = temp; + if (!string) + return -ENODEV; + + /* take the right side and strip off the '"' */ + while (isspace(*string)) + ++string; + if (*string == '"') + ++string; + else + return -ENODEV; + + temp = strsep(&string, "\""); + if (!string || *temp == '\0') + return -ENODEV; + *right = temp; + *orig_string = string; + + return 0; +} + int file_map(const char *filename, char **buf, size_t *bufsize) { struct stat stats; @@ -143,11 +179,21 @@ void file_unmap(char *buf, size_t bufsize) munmap(buf, bufsize); } -size_t buf_get_line(char *buf, size_t buflen, size_t cur) +/* return number of chars until the next newline, skip escaped newline */ +size_t buf_get_line(const char *buf, size_t buflen, size_t cur) { - size_t count = 0; + int escape = 0; + size_t count; + + for (count = cur; count < buflen; count++) { + if (!escape && buf[count] == '\n') + break; - for (count = cur; count < buflen && buf[count] != '\n'; count++); + if (buf[count] == '\\') + escape = 1; + else + escape = 0; + } return count - cur; } diff --git a/udev_utils.h b/udev_utils.h index e36255f5..cc9dd704 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -79,9 +79,10 @@ do { \ extern void udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem); extern int kernel_release_satisfactory(int version, int patchlevel, int sublevel); extern int create_path(const char *path); +extern int parse_get_pair(char **orig_string, char **left, char **right); extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); -extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); +extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); extern void no_trailing_slash(char *path); typedef int (*file_fnct_t)(const char *filename, void *data); extern int call_foreach_file(file_fnct_t fnct, const char *dirname,