Remove all the escape characters that come before separator. Tested this code by writing a dummy program containing the two functions and testing it on below input, sharing results: Original string: "field1\,with\,commas,field2\,with\,more\,commas" Field: "field1" Field: "with" Field: "commas" Field: "field2" Field: "with" Field: "more" Field: "commas" Signed-off-by: Abhinav Jain <jain.abhinav177@xxxxxxxxx> --- PATCH v1: https://lore.kernel.org/all/20240609141721.52344-1-jain.abhinav177@xxxxxxxxx/ Changes since v1: - Modified the str_field_delimit function as per shared feedback - Added remove_escaped_characters function --- --- drivers/md/dm-init.c | 53 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/drivers/md/dm-init.c b/drivers/md/dm-init.c index 2a71bcdba92d..0e31ecf1b48e 100644 --- a/drivers/md/dm-init.c +++ b/drivers/md/dm-init.c @@ -76,6 +76,24 @@ static void __init dm_setup_cleanup(struct list_head *devices) } } +/* Remove escape characters from a given field string. */ +static void __init remove_escape_characters(char *field) +{ + char *src = field; + char *dest = field; + + while (*src) { + if (*src == '\\') { + src++; + if (*src) + *dest++ = *src++; + } else { + *dest++ = *src++; + } + } + *dest = '\0'; +} + /** * str_field_delimit - delimit a string based on a separator char. * @str: the pointer to the string to delimit. @@ -87,16 +105,39 @@ static void __init dm_setup_cleanup(struct list_head *devices) */ static char __init *str_field_delimit(char **str, char separator) { - char *s; + char *s, *escaped, *field; - /* TODO: add support for escaped characters */ *str = skip_spaces(*str); s = strchr(*str, separator); - /* Delimit the field and remove trailing spaces */ - if (s) + + /* Check for escaped character */ + escaped = strchr(*str, '\\'); + while (escaped && (s == NULL || escaped < s)) { + /* + * Move the separator search ahead if escaped + * character comes before. + */ + s = strchr(escaped + 1, separator); + escaped = strchr(escaped + 1, '\\'); + } + + /* If we found a separator, we need to handle escape characters */ + if (s) { + *s = '\0'; + + remove_escape_characters(*str); + field = *str; + *str = s + 1; + } else { + /* Handle the last field when no separator is present */ + s = *str + strlen(*str); *s = '\0'; - *str = strim(*str); - return s ? ++s : NULL; + + remove_escape_characters(*str); + field = *str; + *str = s; + } + return field; } /** -- 2.34.1