chiark / gitweb /
tree-wide: remove Lennart's copyright lines
[elogind.git] / src / basic / string-util.c
index cb6428e8a825a4382252b0bb8c602b9a83ad0eba..7abbfe0c423af633949a5c992836fd7ed26ae06c 100644 (file)
@@ -1,9 +1,4 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
-/***
-  This file is part of systemd.
-
-  Copyright 2010 Lennart Poettering
-***/
 
 #include <errno.h>
 #include <stdarg.h>
@@ -269,23 +264,12 @@ char *strjoin_real(const char *x, ...) {
 }
 
 char *strstrip(char *s) {
-        char *e;
-
         if (!s)
                 return NULL;
 
-        /* Drops trailing whitespace. Modifies the string in
-         * place. Returns pointer to first non-space character */
-
-        s += strspn(s, WHITESPACE);
-
-        for (e = strchr(s, 0); e > s; e --)
-                if (!strchr(WHITESPACE, e[-1]))
-                        break;
-
-        *e = 0;
+        /* Drops trailing whitespace. Modifies the string in place. Returns pointer to first non-space character */
 
-        return s;
+        return delete_trailing_chars(skip_leading_chars(s, WHITESPACE), WHITESPACE);
 }
 
 #if 0 /// UNNEEDED by elogind
@@ -473,8 +457,8 @@ static int write_ellipsis(char *buf, bool unicode) {
 }
 
 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
-        size_t x, need_space;
-        char *r;
+        size_t x, need_space, suffix_len;
+        char *t;
 
         assert(s);
         assert(percent <= 100);
@@ -510,8 +494,8 @@ static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_le
          * either for the UTF-8 encoded character or for three ASCII characters. */
         need_space = is_locale_utf8() ? 1 : 3;
 
-        r = new(char, new_length+3);
-        if (!r)
+        t = new(char, new_length+3);
+        if (!t)
                 return NULL;
 
         assert(new_length >= need_space);
@@ -519,13 +503,13 @@ static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_le
         x = ((new_length - need_space) * percent + 50) / 100;
         assert(x <= new_length - need_space);
 
-        memcpy(r, s, x);
-        write_ellipsis(r + x, false);
-        memcpy(r + x + 3,
-               s + old_length - (new_length - x - need_space),
-               new_length - x - need_space + 1);
+        memcpy(t, s, x);
+        write_ellipsis(t + x, false);
+        suffix_len = new_length - x - need_space;
+        memcpy(t + x + 3, s + old_length - suffix_len, suffix_len);
+        *(t + x + 3 + suffix_len) = '\0';
 
-        return r;
+        return t;
 }
 
 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
@@ -556,42 +540,56 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
                 return strdup("");
 
         /* If no multibyte characters use ascii_ellipsize_mem for speed */
-        if (ascii_is_valid(s))
+        if (ascii_is_valid_n(s, old_length))
                 return ascii_ellipsize_mem(s, old_length, new_length, percent);
 
         x = ((new_length - 1) * percent) / 100;
         assert(x <= new_length - 1);
 
         k = 0;
-        for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
+        for (i = s; i < s + old_length; i = utf8_next_char(i)) {
                 char32_t c;
+                int w;
 
                 r = utf8_encoded_to_unichar(i, &c);
                 if (r < 0)
                         return NULL;
-                k += unichar_iswide(c) ? 2 : 1;
-        }
 
-        if (k > x) /* last character was wide and went over quota */
-                x++;
+                w = unichar_iswide(c) ? 2 : 1;
+                if (k + w <= x)
+                        k += w;
+                else
+                        break;
+        }
 
-        for (j = s + old_length; k < new_length && j > i; ) {
+        for (j = s + old_length; j > i; ) {
                 char32_t c;
+                int w;
+                const char *jj;
 
-                j = utf8_prev_char(j);
-                r = utf8_encoded_to_unichar(j, &c);
+                jj = utf8_prev_char(j);
+                r = utf8_encoded_to_unichar(jj, &c);
                 if (r < 0)
                         return NULL;
-                k += unichar_iswide(c) ? 2 : 1;
+
+                w = unichar_iswide(c) ? 2 : 1;
+                if (k + w <= new_length) {
+                        k += w;
+                        j = jj;
+                } else
+                        break;
         }
         assert(i <= j);
 
         /* we don't actually need to ellipsize */
         if (i == j)
-                return memdup(s, old_length + 1);
+                return memdup_suffix0(s, old_length);
 
-        /* make space for ellipsis */
-        j = utf8_next_char(j);
+        /* make space for ellipsis, if possible */
+        if (j < s + old_length)
+                j = utf8_next_char(j);
+        else if (i > s)
+                i = utf8_prev_char(i);
 
         len = i - s;
         len2 = s + old_length - j;
@@ -606,18 +604,12 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
 
         memcpy(e, s, len);
         write_ellipsis(e + len, true);
-        memcpy(e + len + 3, j, len2 + 1);
+        memcpy(e + len + 3, j, len2);
+        *(e + len + 3 + len2) = '\0';
 
         return e;
 }
 
-char *ellipsize(const char *s, size_t length, unsigned percent) {
-        if (length == (size_t) -1)
-                return strdup(s);
-
-        return ellipsize_mem(s, strlen(s), length, percent);
-}
-
 char *cellescape(char *buf, size_t len, const char *s) {
         /* Escape and ellipsize s into buffer buf of size len. Only non-control ASCII
          * characters are copied as they are, everything else is escaped. The result