#include <unistr.h>
#include "libpspp/cast.h"
+#include "libpspp/i18n.h"
#include "libpspp/message.h"
#include "libpspp/pool.h"
memcpy (dst, src, dst_size);
else
{
- size_t pad_cnt = dst_size - src_len;
- memset (&dst[0], pad, pad_cnt);
- memcpy (dst + pad_cnt, src, src_len);
+ size_t n_pad = dst_size - src_len;
+ memset (&dst[0], pad, n_pad);
+ memcpy (dst + n_pad, src, src_len);
}
}
return false;
}
+/* Copies IN to buffer OUT with size OUT_SIZE, appending a null terminator. If
+ IN is too long for OUT, or if IN contains a new-line, replaces the tail with
+ "...".
+
+ OUT_SIZE must be at least 16. */
+void
+str_ellipsize (struct substring in, char *out, size_t out_size)
+{
+ assert (out_size >= 16);
+
+ size_t out_maxlen = out_size - 1;
+ if (in.length > out_maxlen - 3)
+ out_maxlen -= 3;
+
+ size_t out_len = 0;
+ while (out_len < in.length
+ && in.string[out_len] != '\n'
+ && in.string[out_len] != '\0'
+ && (in.string[out_len] != '\r'
+ || out_len + 1 >= in.length
+ || in.string[out_len + 1] != '\n'))
+ {
+ int mblen = u8_mblen (CHAR_CAST (const uint8_t *, in.string + out_len),
+ in.length - out_len);
+ if (mblen < 0 || out_len + mblen > out_maxlen)
+ break;
+ out_len += mblen;
+ }
+
+ memcpy (out, in.string, out_len);
+ strcpy (&out[out_len], out_len < in.length ? "..." : "");
+}
+
/* Sets the SIZE bytes starting at BLOCK to C,
and returns the byte following BLOCK. */
void *
free (ss->string);
}
+/* Exchanges the contents of A and B. */
+void
+ss_swap (struct substring *a, struct substring *b)
+{
+ struct substring tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
/* Truncates SS to at most CNT bytes in length. */
void
ss_truncate (struct substring *ss, size_t cnt)
else
return 0;
}
+
+size_t
+ss_utf8_count_columns (struct substring s)
+{
+ return utf8_count_columns (s.string, s.length);
+}
+
+/* Returns a substring of S starting at 0-based display column START and
+ running for N display columns. */
+struct substring
+ss_utf8_columns (struct substring s, size_t start, size_t n)
+{
+ ss_advance (&s, utf8_columns_to_bytes (s.string, s.length, start));
+ s.length = utf8_columns_to_bytes (s.string, s.length, n);
+ return s;
+}
\f
/* Initializes ST as an empty string. */
void
void
ds_put_substring (struct string *st, struct substring ss)
{
- memcpy (ds_put_uninit (st, ss_length (ss)), ss_data (ss), ss_length (ss));
+ if (ss.length)
+ memcpy (ds_put_uninit (st, ss_length (ss)), ss_data (ss), ss_length (ss));
}
/* Returns ds_end(ST) and THEN increases the length by INCR. */