diff --git a/include/strutils.h b/include/strutils.h index 4c5d18b48..09cc35e25 100644 --- a/include/strutils.h +++ b/include/strutils.h @@ -310,6 +310,33 @@ static inline size_t ltrim_whitespace(unsigned char *str) return len; } +/* Removes left-hand, right-hand and repeating whitespaces. + */ +static inline size_t normalize_whitespace(unsigned char *str) +{ + size_t i, x, sz = strlen((char *) str); + int nsp = 0, intext = 0; + + if (!sz) + return 0; + + for (i = 0, x = 0; i < sz; ) { + if (isspace(str[i])) + nsp++; + else + nsp = 0, intext = 1; + + if (nsp > 1 || (nsp && !intext)) + i++; + else + str[x++] = str[i++]; + } + if (nsp) /* tailing space */ + x--; + str[x] = '\0'; + return x; +} + static inline void strrep(char *s, int find, int replace) { while (s && *s && (s = strchr(s, find)) != NULL) diff --git a/lib/strutils.c b/lib/strutils.c index 304f31407..eec4cd5fa 100644 --- a/lib/strutils.c +++ b/lib/strutils.c @@ -1114,6 +1114,23 @@ static int test_strutils_cmp_paths(int argc, char *argv[]) return EXIT_SUCCESS; } +static int test_strutils_normalize(int argc, char *argv[]) +{ + unsigned char *str; + size_t sz; + + if (argc < 2) + return EXIT_FAILURE; + + str = (unsigned char *) strdup(argv[1]); + sz = normalize_whitespace(str); + + printf("'%s' --> '%s' [sz=%zu]\n", argv[1], str, sz); + free(str); + + return EXIT_SUCCESS; +} + int main(int argc, char *argv[]) { if (argc == 3 && strcmp(argv[1], "--size") == 0) @@ -1125,10 +1142,17 @@ int main(int argc, char *argv[]) if (argc == 4 && strcmp(argv[1], "--strdup-member") == 0) return test_strdup_to_member(argc - 1, argv + 1); - fprintf(stderr, "usage: %1$s --size [suffix]\n" - " %1$s --cmp-paths \n" - " %1$s --strdup-member \n", - argv[0]); + else if (argc == 3 && strcmp(argv[1], "--normalize") == 0) + return test_strutils_normalize(argc - 1, argv + 1); + + else { + fprintf(stderr, "usage: %1$s --size [suffix]\n" + " %1$s --cmp-paths \n" + " %1$s --strdup-member \n" + " %1$s --normalize \n", + argv[0]); + exit(EXIT_FAILURE); + } return EXIT_FAILURE; }