aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/message.c24
1 files changed, 18 insertions, 6 deletions
diff --git a/src/nvim/message.c b/src/nvim/message.c
index cfcfc9e05f..3667cf3be5 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -3142,7 +3142,7 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
// if both ' ' and '+' flags appear, ' ' flag should be ignored
int space_for_positive = 1;
- // allowed values: \0, h, l, 2 (for ll), L
+ // allowed values: \0, h, l, 2 (for ll), z, L
char length_modifier = '\0';
// temporary buffer for simple numeric->string conversion
@@ -3214,7 +3214,7 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
p++;
precision_specified = 1;
if (*p == '*') {
- int j = tvs != NULL ? tv_nr(tvs, &arg_idx) : va_arg(ap, int);
+ int j = tvs ? tv_nr(tvs, &arg_idx) : va_arg(ap, int);
p++;
if (j >= 0)
precision = j;
@@ -3233,8 +3233,8 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
}
}
- // parse 'h', 'l' and 'll' length modifiers
- if (*p == 'h' || *p == 'l') {
+ // parse 'h', 'l', 'll' and 'z' length modifiers
+ if (*p == 'h' || *p == 'l' || *p == 'z') {
length_modifier = *p;
p++;
if (length_modifier == 'l' && *p == 'l') { // ll, encoded as 2
@@ -3289,8 +3289,10 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
else {
// memchr on HP does not like n > 2^31
// TODO(elmart): check if this still holds / is relevant
- char *q = memchr(str_arg, '\0', MIN(precision, 0x7fffffff));
- str_arg_l = q ? (size_t)(q - str_arg) : precision;
+ str_arg_l = (size_t)((char *)xmemscan(str_arg,
+ NUL,
+ MIN(precision, 0x7fffffff))
+ - str_arg);
}
if (fmt_spec == 'S') {
if (min_field_width != 0)
@@ -3331,6 +3333,9 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
long long int long_long_arg = 0;
unsigned long long int ulong_long_arg = 0;
+ // only defined for length modifier z
+ size_t size_t_arg = 0;
+
// only defined for p conversion
void *ptr_arg = NULL;
@@ -3388,6 +3393,11 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
: va_arg(ap, unsigned long long int);
if (ulong_long_arg) arg_sign = 1;
break;
+ case 'z':
+ size_t_arg = tvs ? (size_t)tv_nr(tvs, &arg_idx)
+ : va_arg(ap, size_t);
+ if (size_t_arg) arg_sign = 1;
+ break;
}
}
@@ -3458,6 +3468,8 @@ int vim_vsnprintf(char *str, size_t str_m, char *fmt, va_list ap, typval_T *tvs)
break;
case '2': str_arg_l += sprintf(tmp + str_arg_l, f, ulong_long_arg);
break;
+ case 'z': str_arg_l += sprintf(tmp + str_arg_l, f, size_t_arg);
+ break;
}
}