aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/strings.c
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2022-07-18 19:37:18 +0000
committerJosh Rahm <rahm@google.com>2022-07-18 19:37:18 +0000
commit308e1940dcd64aa6c344c403d4f9e0dda58d9c5c (patch)
tree35fe43e01755e0f312650667004487a44d6b7941 /src/nvim/strings.c
parent96a00c7c588b2f38a2424aeeb4ea3581d370bf2d (diff)
parente8c94697bcbe23a5c7b07c292b90a6b70aadfa87 (diff)
downloadrneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.tar.gz
rneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.tar.bz2
rneovim-308e1940dcd64aa6c344c403d4f9e0dda58d9c5c.zip
Merge remote-tracking branch 'upstream/master' into rahm
Diffstat (limited to 'src/nvim/strings.c')
-rw-r--r--src/nvim/strings.c125
1 files changed, 89 insertions, 36 deletions
diff --git a/src/nvim/strings.c b/src/nvim/strings.c
index e2a8108c45..5c2721536d 100644
--- a/src/nvim/strings.c
+++ b/src/nvim/strings.c
@@ -67,6 +67,13 @@ char_u *vim_strnsave(const char_u *string, size_t len)
return (char_u *)strncpy(xmallocz(len), (char *)string, len);
}
+/// A clone of vim_strnsave() that uses char* instead of char_u*
+char *xstrnsave(const char *string, size_t len)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_ALL
+{
+ return strncpy(xmallocz(len), string, len); // NOLINT(runtime/printf)
+}
+
/*
* Same as vim_strsave(), but any characters found in esc_chars are preceded
* by a backslash.
@@ -91,14 +98,14 @@ char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars, c
*/
size_t length = 1; // count the trailing NUL
for (const char_u *p = string; *p; p++) {
- const size_t l = (size_t)(utfc_ptr2len(p));
+ const size_t l = (size_t)(utfc_ptr2len((char *)p));
if (l > 1) {
length += l; // count a multibyte char
p += l - 1;
continue;
}
- if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) {
- ++length; // count a backslash
+ if (vim_strchr((char *)esc_chars, *p) != NULL || (bsl && rem_backslash(p))) {
+ length++; // count a backslash
}
++length; // count an ordinary char
}
@@ -106,14 +113,14 @@ char_u *vim_strsave_escaped_ext(const char_u *string, const char_u *esc_chars, c
char_u *escaped_string = xmalloc(length);
char_u *p2 = escaped_string;
for (const char_u *p = string; *p; p++) {
- const size_t l = (size_t)(utfc_ptr2len(p));
+ const size_t l = (size_t)(utfc_ptr2len((char *)p));
if (l > 1) {
memcpy(p2, p, l);
p2 += l;
p += l - 1; // skip multibyte char
continue;
}
- if (vim_strchr(esc_chars, *p) != NULL || (bsl && rem_backslash(p))) {
+ if (vim_strchr((char *)esc_chars, *p) != NULL || (bsl && rem_backslash(p))) {
*p2++ = cc;
}
*p2++ = *p;
@@ -139,7 +146,7 @@ char *vim_strnsave_unquoted(const char *const string, const size_t length)
FUNC_ATTR_NONNULL_RET
{
#define ESCAPE_COND(p, inquote, string_end) \
- (*p == '\\' && inquote && p + 1 < string_end && (p[1] == '\\' || p[1] == '"'))
+ (*(p) == '\\' && (inquote) && (p) + 1 < (string_end) && ((p)[1] == '\\' || (p)[1] == '"'))
size_t ret_length = 0;
bool inquote = false;
const char *const string_end = string + length;
@@ -350,11 +357,11 @@ char *strcase_save(const char *const orig, bool upper)
char *p = res;
while (*p != NUL) {
- int c = utf_ptr2char((const char_u *)p);
- int l = utf_ptr2len((const char_u *)p);
+ int c = utf_ptr2char(p);
+ int l = utf_ptr2len(p);
if (c == 0) {
// overlong sequence, use only the first byte
- c = *p;
+ c = (char_u)(*p);
l = 1;
}
int uc = upper ? mb_toupper(c) : mb_tolower(c);
@@ -372,7 +379,7 @@ char *strcase_save(const char *const orig, bool upper)
res = s;
}
- utf_char2bytes(uc, (char_u *)p);
+ utf_char2bytes(uc, p);
p += newl;
}
@@ -401,7 +408,7 @@ size_t xstrnlen(const char *s, size_t n)
if (end == NULL) {
return n;
}
- return end - s;
+ return (size_t)(end - s);
}
#endif
@@ -466,18 +473,18 @@ int vim_strnicmp(const char *s1, const char *s2, size_t len)
/// @return Pointer to the first byte of the found character in string or NULL
/// if it was not found or character is invalid. NUL character is never
/// found, use `strlen()` instead.
-char_u *vim_strchr(const char_u *const string, const int c)
+char *vim_strchr(const char *const string, const int c)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
if (c <= 0) {
return NULL;
} else if (c < 0x80) {
- return (char_u *)strchr((const char *)string, c);
+ return strchr(string, c);
} else {
char u8char[MB_MAXBYTES + 1];
- const int len = utf_char2bytes(c, (char_u *)u8char);
+ const int len = utf_char2bytes(c, u8char);
u8char[len] = NUL;
- return (char_u *)strstr((const char *)string, u8char);
+ return strstr(string, u8char);
}
}
@@ -546,7 +553,6 @@ char_u *concat_str(const char_u *restrict str1, const char_u *restrict str2)
return dest;
}
-
static const char *const e_printf =
N_("E766: Insufficient arguments for printf()");
@@ -627,7 +633,7 @@ static const void *tv_ptr(const typval_T *const tvs, int *const idxp)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
#define OFF(attr) offsetof(union typval_vval_union, attr)
- STATIC_ASSERT(OFF(v_string) == OFF(v_list)
+ STATIC_ASSERT(OFF(v_string) == OFF(v_list) // -V568
&& OFF(v_string) == OFF(v_dict)
&& OFF(v_string) == OFF(v_partial)
&& sizeof(tvs[0].vval.v_string) == sizeof(tvs[0].vval.v_list)
@@ -1001,22 +1007,20 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap, t
- str_arg);
}
if (fmt_spec == 'S') {
- if (min_field_width != 0) {
- min_field_width += (strlen(str_arg)
- - mb_string2cells((char_u *)str_arg));
- }
- if (precision) {
- char_u *p1;
- size_t i = 0;
-
- for (p1 = (char_u *)str_arg; *p1;
- p1 += utfc_ptr2len(p1)) {
- i += (size_t)utf_ptr2cells(p1);
- if (i > precision) {
- break;
- }
+ char_u *p1;
+ size_t i;
+
+ for (i = 0, p1 = (char_u *)str_arg; *p1; p1 += utfc_ptr2len((char *)p1)) {
+ size_t cell = (size_t)utf_ptr2cells((char *)p1);
+ if (precision_specified && i + cell > precision) {
+ break;
}
- str_arg_l = (size_t)(p1 - (char_u *)str_arg);
+ i += cell;
+ }
+
+ str_arg_l = (size_t)(p1 - (char_u *)str_arg);
+ if (min_field_width != 0) {
+ min_field_width += str_arg_l - i;
}
}
break;
@@ -1308,8 +1312,7 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap, t
if (fmt_spec == 'f' || fmt_spec == 'F') {
tp = tmp + str_arg_l - 1;
} else {
- tp = (char *)vim_strchr((char_u *)tmp,
- fmt_spec == 'e' ? 'e' : 'E');
+ tp = vim_strchr(tmp, fmt_spec == 'e' ? 'e' : 'E');
if (tp) {
// remove superfluous '+' and leading zeroes from exponent
if (tp[1] == '+') {
@@ -1338,8 +1341,7 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap, t
} else {
// Be consistent: some printf("%e") use 1.0e+12 and some
// 1.0e+012; remove one zero in the last case.
- char *tp = (char *)vim_strchr((char_u *)tmp,
- fmt_spec == 'e' ? 'e' : 'E');
+ char *tp = vim_strchr(tmp, fmt_spec == 'e' ? 'e' : 'E');
if (tp && (tp[1] == '+' || tp[1] == '-') && tp[2] == '0'
&& ascii_isdigit(tp[3]) && ascii_isdigit(tp[4])) {
STRMOVE(tp + 2, tp + 3);
@@ -1475,3 +1477,54 @@ int vim_vsnprintf_typval(char *str, size_t str_m, const char *fmt, va_list ap, t
// written to the buffer if it were large enough.
return (int)str_l;
}
+
+int kv_do_printf(StringBuilder *str, const char *fmt, ...)
+ FUNC_ATTR_PRINTF(2, 3)
+{
+ size_t remaining = str->capacity - str->size;
+
+ va_list ap;
+ va_start(ap, fmt);
+ int printed = vsnprintf(str->items ? str->items + str->size : NULL, remaining, fmt, ap);
+ va_end(ap);
+
+ if (printed < 0) {
+ return -1;
+ }
+
+ // printed string didn't fit, resize and try again
+ if ((size_t)printed >= remaining) {
+ kv_ensure_space(*str, (size_t)printed + 1); // include space for NUL terminator at the end
+ assert(str->items != NULL);
+ va_start(ap, fmt);
+ printed = vsnprintf(str->items + str->size, str->capacity - str->size, fmt, ap);
+ va_end(ap);
+ if (printed < 0) {
+ return -1;
+ }
+ }
+
+ str->size += (size_t)printed;
+ return printed;
+}
+
+/// Reverse text into allocated memory.
+///
+/// @return the allocated string.
+char_u *reverse_text(char_u *s)
+ FUNC_ATTR_NONNULL_RET
+{
+ // Reverse the pattern.
+ size_t len = STRLEN(s);
+ char_u *rev = xmalloc(len + 1);
+ size_t rev_i = len;
+ for (size_t s_i = 0; s_i < len; s_i++) {
+ const int mb_len = utfc_ptr2len((char *)s + s_i);
+ rev_i -= (size_t)mb_len;
+ memmove(rev + rev_i, s + s_i, (size_t)mb_len);
+ s_i += (size_t)mb_len - 1;
+ }
+ rev[len] = NUL;
+
+ return rev;
+}