diff options
author | Dan Streetman <ddstreet@ieee.org> | 2017-01-26 14:18:10 -0500 |
---|---|---|
committer | Dan Streetman <ddstreet@ieee.org> | 2017-01-27 07:58:00 -0500 |
commit | be45268352d9faeca663941141a57ef728e2fc47 (patch) | |
tree | 32f20637e5585e84fbd3295bbbfcf979ffe7be69 | |
parent | 0d53705b65b496f979a816a15181c5b1cda7a90f (diff) |
udev-event: use in-place whitespace replacement
Instead of using a temp buffer to replace whitespace in variable
substitutions, just allow util_replace_whitespace to replace in-place.
Add a comment to util_replace_whitespace indicating it is used to replace
in-place, to prevent accidental future breakage.
-rw-r--r-- | src/libudev/libudev-util.c | 14 | ||||
-rw-r--r-- | src/udev/udev-event.c | 50 |
2 files changed, 29 insertions, 35 deletions
diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c index a9819b9db3..1d73d8f090 100644 --- a/src/libudev/libudev-util.c +++ b/src/libudev/libudev-util.c @@ -161,6 +161,20 @@ void util_remove_trailing_chars(char *path, char c) path[--len] = '\0'; } +/* + * Copy from 'str' to 'to', while removing all leading and trailing whitespace, + * and replacing each run of consecutive whitespace with a single underscore. + * The chars from 'str' are copied up to the \0 at the end of the string, or + * at most 'len' chars. This appends \0 to 'to', at the end of the copied + * characters. + * + * If 'len' chars are copied into 'to', the final \0 is placed at len+1 + * (i.e. 'to[len] = \0'), so the 'to' buffer must have at least len+1 + * chars available. + * + * Note this may be called with 'str' == 'to', i.e. to replace whitespace + * in-place in a buffer. This function can handle that situation. + */ int util_replace_whitespace(const char *str, char *to, size_t len) { size_t i, j; diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 3cb2673291..3f9c3ed0cf 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -95,8 +95,8 @@ enum subst_type { static size_t subst_format_var(struct udev_event *event, struct udev_device *dev, enum subst_type type, char *attr, - char **dest, size_t l) { - char *s = *dest; + char *dest, size_t l) { + char *s = dest; switch (type) { case SUBST_DEVPATH: @@ -279,9 +279,7 @@ static size_t subst_format_var(struct udev_event *event, struct udev_device *dev break; } - *dest = s; - - return l; + return s - dest; } size_t udev_event_apply_format(struct udev_event *event, @@ -324,10 +322,9 @@ size_t udev_event_apply_format(struct udev_event *event, for (;;) { enum subst_type type = SUBST_UNKNOWN; - char attrbuf[UTIL_PATH_SIZE], sbuf[UTIL_PATH_SIZE]; - char *attr = NULL, *_s; - size_t _l; - bool replws = replace_whitespace; + char attrbuf[UTIL_PATH_SIZE]; + char *attr = NULL; + size_t subst_len; while (from[0] != '\0') { if (from[0] == '$') { @@ -396,34 +393,17 @@ subst: attr = NULL; } - /* result subst handles space as field separator */ - if (type == SUBST_RESULT) - replws = false; - - if (replws) { - /* store dest string ptr and remaining len */ - _s = s; - _l = l; - /* temporarily use sbuf */ - s = sbuf; - l = UTIL_PATH_SIZE; - } - - l = subst_format_var(event, dev, type, attr, &s, l); - - /* replace whitespace in sbuf and copy to dest */ - if (replws) { - size_t tmplen = UTIL_PATH_SIZE - l; + subst_len = subst_format_var(event, dev, type, attr, s, l); - /* restore s and l to dest string values */ - s = _s; - l = _l; + /* SUBST_RESULT handles spaces itself */ + if (replace_whitespace && type != SUBST_RESULT) + /* util_replace_whitespace can replace in-place, + * and does nothing if subst_len == 0 + */ + subst_len = util_replace_whitespace(s, s, subst_len); - /* copy ws-replaced value to s */ - tmplen = util_replace_whitespace(sbuf, s, MIN(tmplen, l)); - l -= tmplen; - s += tmplen; - } + s += subst_len; + l -= subst_len; } out: |