aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cjson/fpconv.h10
-rw-r--r--src/cjson/lua_cjson.c177
-rw-r--r--src/cjson/strbuf.c113
-rw-r--r--src/cjson/strbuf.h52
-rw-r--r--src/nvim/eval.c2
-rw-r--r--src/nvim/runtime.c46
6 files changed, 219 insertions, 181 deletions
diff --git a/src/cjson/fpconv.h b/src/cjson/fpconv.h
index 6ac97808b6..791864fe39 100644
--- a/src/cjson/fpconv.h
+++ b/src/cjson/fpconv.h
@@ -7,10 +7,20 @@
# define FPCONV_G_FMT_BUFSIZE 32
#ifdef USE_INTERNAL_FPCONV
+// #ifdef MULTIPLE_THREADS
+// #include "dtoa_config.h"
+// #include <unistd.h>
+// static inline void fpconv_init()
+// {
+// // Add one to try and avoid core id multiplier alignment
+// set_max_dtoa_threads((sysconf(_SC_NPROCESSORS_CONF) + 1) * 3);
+// }
+// #else
static inline void fpconv_init()
{
/* Do nothing - not required */
}
+// #endif
#else
extern void fpconv_init(void);
#endif
diff --git a/src/cjson/lua_cjson.c b/src/cjson/lua_cjson.c
index e4bd0bcf6b..bcd464061c 100644
--- a/src/cjson/lua_cjson.c
+++ b/src/cjson/lua_cjson.c
@@ -1,4 +1,5 @@
// Upstream: https://github.com/openresty/lua-cjson/blob/master/lua_cjson.c
+// Synced Commit; 91ca29db9a4a4fd0eedaebcd5d5f3ba2ace5ae63
/* Lua CJSON - JSON support for Lua
*
@@ -42,6 +43,7 @@
#include <stdint.h>
#include <string.h>
#include <math.h>
+// #include <stdint.h>
#include <limits.h>
#include <lua.h>
#include <lauxlib.h>
@@ -57,17 +59,14 @@
#endif
#ifndef CJSON_VERSION
-#define CJSON_VERSION "2.1.0.9"
+#define CJSON_VERSION "2.1.0.11"
#endif
#ifdef _MSC_VER
-#define snprintf sprintf_s
-
-#ifndef isnan
-#include <float.h>
-#define isnan(x) _isnan(x)
-#endif
-
+// #define CJSON_EXPORT __declspec(dllexport)
+// #define strncasecmp(x,y,z) _strnicmp(x,y,z)
+#else
+#define CJSON_EXPORT extern
#endif
/* Workaround for Solaris platforms missing isinf() */
@@ -87,6 +86,7 @@
#define DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT 0
#define DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT 0
#define DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH 1
+#define DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES 0
#ifdef DISABLE_INVALID_NUMBERS
#undef DEFAULT_DECODE_INVALID_NUMBERS
@@ -107,8 +107,8 @@
#define json_lightudata_mask(ludata) (ludata)
#endif
-#if LUA_VERSION_NUM > 501
-#define lua_objlen(L,i) lua_rawlen(L, (i))
+#if LUA_VERSION_NUM >= 502
+#define lua_objlen(L,i) luaL_len(L, (i))
#endif
static const char * const *json_empty_array;
@@ -121,6 +121,7 @@ typedef enum {
T_ARR_END,
T_STRING,
T_NUMBER,
+ T_INTEGER,
T_BOOLEAN,
T_NULL,
T_COLON,
@@ -138,6 +139,7 @@ static const char *json_token_type_name[] = {
"T_ARR_END",
"T_STRING",
"T_NUMBER",
+ "T_INTEGER",
"T_BOOLEAN",
"T_NULL",
"T_COLON",
@@ -170,6 +172,7 @@ typedef struct {
int decode_invalid_numbers;
int decode_max_depth;
int decode_array_with_array_mt;
+ int encode_skip_unsupported_value_types;
} json_config_t;
typedef struct {
@@ -200,13 +203,14 @@ typedef struct {
typedef struct {
json_token_type_t type;
- int index;
+ size_t index;
union {
const char *string;
double number;
+ lua_Integer integer;
int boolean;
} value;
- int string_len;
+ size_t string_len;
} json_token_t;
static const char *char2escape[256] = {
@@ -254,7 +258,7 @@ static json_config_t *json_fetch_config(lua_State *l)
{
json_config_t *cfg;
- cfg = lua_touserdata(l, lua_upvalueindex(1));
+ cfg = (json_config_t *)lua_touserdata(l, lua_upvalueindex(1));
if (!cfg)
luaL_error(l, "BUG: Unable to fetch CJSON configuration");
@@ -397,6 +401,18 @@ static int json_cfg_decode_array_with_array_mt(lua_State *l)
}
*/
+/* Configure how to treat invalid types */
+/*
+static int json_cfg_encode_skip_unsupported_value_types(lua_State *l)
+{
+ json_config_t *cfg = json_arg_init(l, 1);
+
+ json_enum_option(l, 1, &cfg->encode_skip_unsupported_value_types, NULL, 1);
+
+ return 1;
+}
+*/
+
/* Configures JSON encoding buffer persistence */
/*
static int json_cfg_encode_keep_buffer(lua_State *l)
@@ -479,7 +495,7 @@ static int json_destroy_config(lua_State *l)
{
json_config_t *cfg;
- cfg = lua_touserdata(l, 1);
+ cfg = (json_config_t *)lua_touserdata(l, 1);
if (cfg)
strbuf_free(&cfg->encode_buf);
cfg = NULL;
@@ -492,7 +508,11 @@ static void json_create_config(lua_State *l)
json_config_t *cfg;
int i;
- cfg = lua_newuserdata(l, sizeof(*cfg));
+ cfg = (json_config_t *)lua_newuserdata(l, sizeof(*cfg));
+ if (!cfg)
+ abort();
+
+ memset(cfg, 0, sizeof(*cfg));
/* Create GC method to clean up strbuf */
lua_newtable(l);
@@ -512,6 +532,7 @@ static void json_create_config(lua_State *l)
cfg->encode_empty_table_as_object = DEFAULT_ENCODE_EMPTY_TABLE_AS_OBJECT;
cfg->decode_array_with_array_mt = DEFAULT_DECODE_ARRAY_WITH_ARRAY_MT;
cfg->encode_escape_forward_slash = DEFAULT_ENCODE_ESCAPE_FORWARD_SLASH;
+ cfg->encode_skip_unsupported_value_types = DEFAULT_ENCODE_SKIP_UNSUPPORTED_VALUE_TYPES;
#if DEFAULT_ENCODE_KEEP_BUFFER > 0
strbuf_init(&cfg->encode_buf, 0);
@@ -583,9 +604,9 @@ static void json_encode_exception(lua_State *l, json_encode_t *ctx, int lindex,
static void json_append_string(lua_State *l, json_encode_t *ctx, int lindex)
{
const char *escstr;
- unsigned i;
const char *str;
size_t len;
+ size_t i;
strbuf_t *json = ctx->json;
str = lua_tolstring(l, lindex, &len);
@@ -594,6 +615,8 @@ static void json_append_string(lua_State *l, json_encode_t *ctx, int lindex)
* This buffer is reused constantly for small strings
* If there are any excess pages, they won't be hit anyway.
* This gains ~5% speedup. */
+ if (len > SIZE_MAX / 6 - 3)
+ abort(); /*Overflow check */
strbuf_ensure_empty_length(json, len * 6 + 2);
strbuf_append_char_unsafe(json, '\"');
@@ -678,30 +701,44 @@ static void json_check_encode_depth(lua_State *l, json_config_t *cfg,
current_depth);
}
-static void json_append_data(lua_State *l, json_encode_t *cfg,
+static int json_append_data(lua_State *l, json_encode_t *cfg,
int current_depth);
/* json_append_array args:
* - lua_State
* - JSON strbuf
- * - Size of passwd Lua array (top of stack) */
+ * - Size of passed Lua array (top of stack) */
static void json_append_array(lua_State *l, json_encode_t *ctx, int current_depth,
- int array_length)
+ int array_length, int raw)
{
- int comma, i;
+ int comma, i, json_pos, err;
strbuf_t *json = ctx->json;
strbuf_append_char(json, '[');
comma = 0;
for (i = 1; i <= array_length; i++) {
- if (comma)
+ json_pos = strbuf_length(json);
+ if (comma++ > 0)
strbuf_append_char(json, ',');
- else
- comma = 1;
+ if (raw) {
+ lua_rawgeti(l, -1, i);
+ } else {
+ #if LUA_VERSION_NUM >= 503
+ lua_geti(l, -1, i);
+ #else
+ lua_pushinteger(l, i);
+ lua_gettable(l, -2);
+ #endif
+ }
- lua_rawgeti(l, -1, i);
- json_append_data(l, ctx, current_depth);
+ err = json_append_data(l, ctx, current_depth);
+ if (err) {
+ strbuf_set_length(json, json_pos);
+ if (comma == 1) {
+ comma = 0;
+ }
+ }
lua_pop(l, 1);
}
@@ -711,8 +748,17 @@ static void json_append_array(lua_State *l, json_encode_t *ctx, int current_dept
static void json_append_number(lua_State *l, json_encode_t *ctx,
int lindex)
{
- double num = lua_tonumber(l, lindex);
int len;
+ #if LUA_VERSION_NUM >= 503
+ if (lua_isinteger(l, lindex)) {
+ lua_Integer num = lua_tointeger(l, lindex);
+ strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE); /* max length of int64 is 19 */
+ len = sprintf(strbuf_empty_ptr(json), LUA_INTEGER_FMT, num);
+ strbuf_extend_length(json, len);
+ return;
+ }
+ #endif
+ double num = lua_tonumber(l, lindex);
json_config_t *cfg = ctx->cfg;
strbuf_t *json = ctx->json;
@@ -751,7 +797,7 @@ static void json_append_number(lua_State *l, json_encode_t *ctx,
static void json_append_object(lua_State *l, json_encode_t *ctx,
int current_depth)
{
- int comma, keytype;
+ int comma, keytype, json_pos, err;
strbuf_t *json = ctx->json;
/* Object */
@@ -761,7 +807,8 @@ static void json_append_object(lua_State *l, json_encode_t *ctx,
/* table, startkey */
comma = 0;
while (lua_next(l, -2) != 0) {
- if (comma)
+ json_pos = strbuf_length(json);
+ if (comma++ > 0)
strbuf_append_char(json, ',');
else
comma = 1;
@@ -782,7 +829,14 @@ static void json_append_object(lua_State *l, json_encode_t *ctx,
}
/* table, key, value */
- json_append_data(l, ctx, current_depth);
+ err = json_append_data(l, ctx, current_depth);
+ if (err) {
+ strbuf_set_length(json, json_pos);
+ if (comma == 1) {
+ comma = 0;
+ }
+ }
+
lua_pop(l, 1);
/* table, key */
}
@@ -790,14 +844,15 @@ static void json_append_object(lua_State *l, json_encode_t *ctx,
strbuf_append_char(json, '}');
}
-/* Serialise Lua data into JSON string. */
-static void json_append_data(lua_State *l, json_encode_t *ctx,
+/* Serialise Lua data into JSON string. Return 1 if error an error happend, else 0 */
+static int json_append_data(lua_State *l, json_encode_t *ctx,
int current_depth)
{
int len;
int as_array = 0;
int as_empty_dict = 0;
int has_metatable;
+ int raw = 1;
json_config_t *cfg = ctx->cfg;
strbuf_t *json = ctx->json;
@@ -831,17 +886,31 @@ static void json_append_data(lua_State *l, json_encode_t *ctx,
lua_rawget(l, LUA_REGISTRYINDEX);
as_array = lua_rawequal(l, -1, -2);
}
- lua_pop(l, 2);
+ if (as_array) {
+ raw = 1;
+ lua_pop(l, 2);
+ len = lua_objlen(l, -1);
+ } else {
+ raw = 0;
+ lua_pop(l, 2);
+ if (luaL_getmetafield(l, -1, "__len")) {
+ lua_pushvalue(l, -2);
+ lua_call(l, 1, 1);
+ len = lua_tonumber(l, -1);
+ lua_pop(l, 1);
+ as_array = 1;
+ }
+ }
}
if (as_array) {
len = lua_objlen(l, -1);
- json_append_array(l, ctx, current_depth, len);
+ json_append_array(l, ctx, current_depth, len, raw);
} else {
len = lua_array_length(l, ctx);
if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object && !as_empty_dict)) {
- json_append_array(l, ctx, current_depth, len);
+ json_append_array(l, ctx, current_depth, len, raw);
} else {
if (has_metatable) {
lua_getmetatable(l, -1);
@@ -851,7 +920,10 @@ static void json_append_data(lua_State *l, json_encode_t *ctx,
as_array = lua_rawequal(l, -1, -2);
lua_pop(l, 2); /* pop pointer + metatable */
if (as_array) {
- json_append_array(l, ctx, current_depth, 0);
+ len = lua_objlen(l, -1);
+
+ raw = 1;
+ json_append_array(l, ctx, current_depth, len, raw);
break;
}
}
@@ -864,7 +936,7 @@ static void json_append_data(lua_State *l, json_encode_t *ctx,
break;
case LUA_TLIGHTUSERDATA:
if (lua_touserdata(l, -1) == &json_array) {
- json_append_array(l, ctx, current_depth, 0);
+ json_append_array(l, ctx, current_depth, 0, 1);
}
break;
case LUA_TUSERDATA:
@@ -880,9 +952,15 @@ static void json_append_data(lua_State *l, json_encode_t *ctx,
default:
/* Remaining types (LUA_TFUNCTION, LUA_TUSERDATA, LUA_TTHREAD,
* and LUA_TLIGHTUSERDATA) cannot be serialised */
+ if (cfg->encode_skip_unsupported_value_types) {
+ return 1;
+ } else {
json_encode_exception(l, ctx, -1, "type not supported");
+ }
+
/* never returns */
}
+ return 0;
}
static int json_encode(lua_State *l)
@@ -893,7 +971,7 @@ static int json_encode(lua_State *l)
strbuf_t local_encode_buf;
strbuf_t *encode_buf;
char *json;
- int len;
+ size_t len;
const char *customChar2escape[256];
switch (lua_gettop(l)) {
@@ -1215,12 +1293,19 @@ static void json_next_number_token(json_parse_t *json, json_token_t *token)
{
char *endptr;
- token->type = T_NUMBER;
- token->value.number = fpconv_strtod(json->ptr, &endptr);
- if (json->ptr == endptr)
- json_set_token_error(token, json, "invalid number");
- else
- json->ptr = endptr; /* Skip the processed number */
+ token->value.integer = strtoll(json->ptr, &endptr, 10);
+ if (json->ptr == endptr || *endptr == '.' || *endptr == 'e' ||
+ *endptr == 'E' || *endptr == 'x') {
+ token->type = T_NUMBER;
+ token->value.number = fpconv_strtod(json->ptr, &endptr);
+ if (json->ptr == endptr) {
+ json_set_token_error(token, json, "invalid number");
+ return;
+ }
+ } else {
+ token->type = T_INTEGER;
+ }
+ json->ptr = endptr; /* Skip the processed number */
return;
}
@@ -1458,6 +1543,9 @@ static void json_process_value(lua_State *l, json_parse_t *json,
case T_NUMBER:
lua_pushnumber(l, token->value.number);
break;;
+ case T_INTEGER:
+ lua_pushinteger(l, token->value.integer);
+ break;;
case T_BOOLEAN:
lua_pushboolean(l, token->value.boolean);
break;;
@@ -1621,6 +1709,7 @@ int lua_cjson_new(lua_State *l)
{ "encode_invalid_numbers", json_cfg_encode_invalid_numbers },
{ "decode_invalid_numbers", json_cfg_decode_invalid_numbers },
{ "encode_escape_forward_slash", json_cfg_encode_escape_forward_slash },
+ { "encode_skip_unsupported_value_types", json_cfg_encode_skip_unsupported_value_types },
*/
{ "new", lua_cjson_new },
{ NULL, NULL }
@@ -1745,5 +1834,3 @@ int luaopen_cjson_safe(lua_State *l)
return 1;
}
-/* vi:ai et sw=4 ts=4:
- */
diff --git a/src/cjson/strbuf.c b/src/cjson/strbuf.c
index f0f7f4b9a3..0bcff9b8cc 100644
--- a/src/cjson/strbuf.c
+++ b/src/cjson/strbuf.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
+#include <stdint.h>
#include "strbuf.h"
@@ -41,35 +42,35 @@ static void die(const char *fmt, ...)
exit(-1);
}
-void strbuf_init(strbuf_t *s, int len)
+void strbuf_init(strbuf_t *s, size_t len)
{
- int size;
+ size_t size;
- if (len <= 0)
+ if (!len)
size = STRBUF_DEFAULT_SIZE;
else
size = len + 1; /* \0 terminator */
-
+ if (size < len)
+ die("Overflow, len %zu", len);
s->buf = NULL;
s->size = size;
s->length = 0;
- s->increment = STRBUF_DEFAULT_INCREMENT;
s->dynamic = 0;
s->reallocs = 0;
s->debug = 0;
- s->buf = malloc(size);
+ s->buf = (char *)malloc(size);
if (!s->buf)
die("Out of memory");
strbuf_ensure_null(s);
}
-strbuf_t *strbuf_new(int len)
+strbuf_t *strbuf_new(size_t len)
{
strbuf_t *s;
- s = malloc(sizeof(strbuf_t));
+ s = (strbuf_t*)malloc(sizeof(strbuf_t));
if (!s)
die("Out of memory");
@@ -81,20 +82,10 @@ strbuf_t *strbuf_new(int len)
return s;
}
-void strbuf_set_increment(strbuf_t *s, int increment)
-{
- /* Increment > 0: Linear buffer growth rate
- * Increment < -1: Exponential buffer growth rate */
- if (increment == 0 || increment == -1)
- die("BUG: Invalid string increment");
-
- s->increment = increment;
-}
-
static inline void debug_stats(strbuf_t *s)
{
if (s->debug) {
- fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %d, size: %d\n",
+ fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %zd, size: %zd\n",
(long)s, s->reallocs, s->length, s->size);
}
}
@@ -113,7 +104,7 @@ void strbuf_free(strbuf_t *s)
free(s);
}
-char *strbuf_free_to_string(strbuf_t *s, int *len)
+char *strbuf_free_to_string(strbuf_t *s, size_t *len)
{
char *buf;
@@ -131,57 +122,63 @@ char *strbuf_free_to_string(strbuf_t *s, int *len)
return buf;
}
-static int calculate_new_size(strbuf_t *s, int len)
+static size_t calculate_new_size(strbuf_t *s, size_t len)
{
- int reqsize, newsize;
+ size_t reqsize, newsize;
if (len <= 0)
die("BUG: Invalid strbuf length requested");
/* Ensure there is room for optional NULL termination */
reqsize = len + 1;
+ if (reqsize < len)
+ die("Overflow, len %zu", len);
/* If the user has requested to shrink the buffer, do it exactly */
if (s->size > reqsize)
return reqsize;
newsize = s->size;
- if (s->increment < 0) {
+ if (reqsize >= SIZE_MAX / 2) {
+ newsize = reqsize;
+ } else {
/* Exponential sizing */
while (newsize < reqsize)
- newsize *= -s->increment;
- } else {
- /* Linear sizing */
- newsize = ((newsize + s->increment - 1) / s->increment) * s->increment;
+ newsize *= 2;
}
+ if (newsize < reqsize)
+ die("BUG: strbuf length would overflow, len: %zu", len);
+
+
return newsize;
}
/* Ensure strbuf can handle a string length bytes long (ignoring NULL
* optional termination). */
-void strbuf_resize(strbuf_t *s, int len)
+void strbuf_resize(strbuf_t *s, size_t len)
{
- int newsize;
+ size_t newsize;
newsize = calculate_new_size(s, len);
if (s->debug > 1) {
- fprintf(stderr, "strbuf(%lx) resize: %d => %d\n",
+ fprintf(stderr, "strbuf(%lx) resize: %zd => %zd\n",
(long)s, s->size, newsize);
}
s->size = newsize;
- s->buf = realloc(s->buf, s->size);
+ s->buf = (char *)realloc(s->buf, s->size);
if (!s->buf)
- die("Out of memory");
+ die("Out of memory, len: %zu", len);
s->reallocs++;
}
void strbuf_append_string(strbuf_t *s, const char *str)
{
- int space, i;
+ int i;
+ size_t space;
space = strbuf_empty_length(s);
@@ -197,55 +194,5 @@ void strbuf_append_string(strbuf_t *s, const char *str)
}
}
-/* strbuf_append_fmt() should only be used when an upper bound
- * is known for the output string. */
-void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...)
-{
- va_list arg;
- int fmt_len;
-
- strbuf_ensure_empty_length(s, len);
-
- va_start(arg, fmt);
- fmt_len = vsnprintf(s->buf + s->length, len, fmt, arg);
- va_end(arg);
-
- if (fmt_len < 0)
- die("BUG: Unable to convert number"); /* This should never happen.. */
-
- s->length += fmt_len;
-}
-
-/* strbuf_append_fmt_retry() can be used when the there is no known
- * upper bound for the output string. */
-void strbuf_append_fmt_retry(strbuf_t *s, const char *fmt, ...)
-{
- va_list arg;
- int fmt_len, try;
- int empty_len;
-
- /* If the first attempt to append fails, resize the buffer appropriately
- * and try again */
- for (try = 0; ; try++) {
- va_start(arg, fmt);
- /* Append the new formatted string */
- /* fmt_len is the length of the string required, excluding the
- * trailing NULL */
- empty_len = strbuf_empty_length(s);
- /* Add 1 since there is also space to store the terminating NULL. */
- fmt_len = vsnprintf(s->buf + s->length, empty_len + 1, fmt, arg);
- va_end(arg);
-
- if (fmt_len <= empty_len)
- break; /* SUCCESS */
- if (try > 0)
- die("BUG: length of formatted string changed");
-
- strbuf_resize(s, s->length + fmt_len);
- }
-
- s->length += fmt_len;
-}
-
/* vi:ai et sw=4 ts=4:
*/
diff --git a/src/cjson/strbuf.h b/src/cjson/strbuf.h
index 5df0b7bea3..bee245701b 100644
--- a/src/cjson/strbuf.h
+++ b/src/cjson/strbuf.h
@@ -32,15 +32,13 @@
/* Size: Total bytes allocated to *buf
* Length: String length, excluding optional NULL terminator.
- * Increment: Allocation increments when resizing the string buffer.
* Dynamic: True if created via strbuf_new()
*/
typedef struct {
char *buf;
- int size;
- int length;
- int increment;
+ size_t size;
+ size_t length;
int dynamic;
int reallocs;
int debug;
@@ -49,32 +47,27 @@ typedef struct {
#ifndef STRBUF_DEFAULT_SIZE
#define STRBUF_DEFAULT_SIZE 1023
#endif
-#ifndef STRBUF_DEFAULT_INCREMENT
-#define STRBUF_DEFAULT_INCREMENT -2
-#endif
/* Initialise */
-extern strbuf_t *strbuf_new(int len);
-extern void strbuf_init(strbuf_t *s, int len);
-extern void strbuf_set_increment(strbuf_t *s, int increment);
+extern strbuf_t *strbuf_new(size_t len);
+extern void strbuf_init(strbuf_t *s, size_t len);
/* Release */
extern void strbuf_free(strbuf_t *s);
-extern char *strbuf_free_to_string(strbuf_t *s, int *len);
+extern char *strbuf_free_to_string(strbuf_t *s, size_t *len);
/* Management */
-extern void strbuf_resize(strbuf_t *s, int len);
-static int strbuf_empty_length(strbuf_t *s);
-static int strbuf_length(strbuf_t *s);
-static char *strbuf_string(strbuf_t *s, int *len);
-static void strbuf_ensure_empty_length(strbuf_t *s, int len);
+extern void strbuf_resize(strbuf_t *s, size_t len);
+static size_t strbuf_empty_length(strbuf_t *s);
+static size_t strbuf_length(strbuf_t *s);
+static char *strbuf_string(strbuf_t *s, size_t *len);
+static void strbuf_ensure_empty_length(strbuf_t *s, size_t len);
static char *strbuf_empty_ptr(strbuf_t *s);
-static void strbuf_extend_length(strbuf_t *s, int len);
+static void strbuf_extend_length(strbuf_t *s, size_t len);
+static void strbuf_set_length(strbuf_t *s, int len);
/* Update */
-extern void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...);
-extern void strbuf_append_fmt_retry(strbuf_t *s, const char *format, ...);
-static void strbuf_append_mem(strbuf_t *s, const char *c, int len);
+static void strbuf_append_mem(strbuf_t *s, const char *c, size_t len);
extern void strbuf_append_string(strbuf_t *s, const char *str);
static void strbuf_append_char(strbuf_t *s, const char c);
static void strbuf_ensure_null(strbuf_t *s);
@@ -92,12 +85,12 @@ static inline int strbuf_allocated(strbuf_t *s)
/* Return bytes remaining in the string buffer
* Ensure there is space for a NULL terminator. */
-static inline int strbuf_empty_length(strbuf_t *s)
+static inline size_t strbuf_empty_length(strbuf_t *s)
{
return s->size - s->length - 1;
}
-static inline void strbuf_ensure_empty_length(strbuf_t *s, int len)
+static inline void strbuf_ensure_empty_length(strbuf_t *s, size_t len)
{
if (len > strbuf_empty_length(s))
strbuf_resize(s, s->length + len);
@@ -108,12 +101,17 @@ static inline char *strbuf_empty_ptr(strbuf_t *s)
return s->buf + s->length;
}
-static inline void strbuf_extend_length(strbuf_t *s, int len)
+static inline void strbuf_set_length(strbuf_t *s, int len)
+{
+ s->length += len;
+}
+
+static inline void strbuf_extend_length(strbuf_t *s, size_t len)
{
s->length += len;
}
-static inline int strbuf_length(strbuf_t *s)
+static inline size_t strbuf_length(strbuf_t *s)
{
return s->length;
}
@@ -129,14 +127,14 @@ static inline void strbuf_append_char_unsafe(strbuf_t *s, const char c)
s->buf[s->length++] = c;
}
-static inline void strbuf_append_mem(strbuf_t *s, const char *c, int len)
+static inline void strbuf_append_mem(strbuf_t *s, const char *c, size_t len)
{
strbuf_ensure_empty_length(s, len);
memcpy(s->buf + s->length, c, len);
s->length += len;
}
-static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, int len)
+static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, size_t len)
{
memcpy(s->buf + s->length, c, len);
s->length += len;
@@ -147,7 +145,7 @@ static inline void strbuf_ensure_null(strbuf_t *s)
s->buf[s->length] = 0;
}
-static inline char *strbuf_string(strbuf_t *s, int *len)
+static inline char *strbuf_string(strbuf_t *s, size_t *len)
{
if (len)
*len = s->length;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index bd15b7110f..2b6fefbf82 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -8038,6 +8038,8 @@ void last_set_msg(sctx_T script_ctx)
if (script_ctx.sc_lnum > 0) {
msg_puts(_(line_msg));
msg_outnum(script_ctx.sc_lnum);
+ } else if (script_is_lua(script_ctx.sc_sid)) {
+ msg_puts(_(" (run Nvim with -V1 for more details)"));
}
if (should_free) {
xfree(p);
diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c
index 8d05169108..b02977e564 100644
--- a/src/nvim/runtime.c
+++ b/src/nvim/runtime.c
@@ -229,8 +229,7 @@ char *estack_sfile(estack_arg_T which)
}
static void stacktrace_push_item(list_T *const l, ufunc_T *const fp, const char *const event,
- const linenr_T lnum, char *const filepath,
- const bool filepath_alloced)
+ const linenr_T lnum, char *const filepath)
{
dict_T *const d = tv_dict_alloc_lock(VAR_FIXED);
typval_T tv = {
@@ -246,11 +245,7 @@ static void stacktrace_push_item(list_T *const l, ufunc_T *const fp, const char
tv_dict_add_str(d, S_LEN("event"), event);
}
tv_dict_add_nr(d, S_LEN("lnum"), lnum);
- if (filepath_alloced) {
- tv_dict_add_allocated_str(d, S_LEN("filepath"), filepath);
- } else {
- tv_dict_add_str(d, S_LEN("filepath"), filepath);
- }
+ tv_dict_add_str(d, S_LEN("filepath"), filepath);
tv_list_append_tv(l, &tv);
}
@@ -265,20 +260,18 @@ list_T *stacktrace_create(void)
linenr_T lnum = entry->es_lnum;
if (entry->es_type == ETYPE_SCRIPT) {
- stacktrace_push_item(l, NULL, NULL, lnum, entry->es_name, false);
+ stacktrace_push_item(l, NULL, NULL, lnum, entry->es_name);
} else if (entry->es_type == ETYPE_UFUNC) {
ufunc_T *const fp = entry->es_info.ufunc;
const sctx_T sctx = fp->uf_script_ctx;
- bool filepath_alloced = false;
- char *filepath = sctx.sc_sid > 0 ? get_scriptname(sctx, &filepath_alloced) : "";
+ char *filepath = sctx.sc_sid > 0 ? get_scriptname(sctx, NULL) : "";
lnum += sctx.sc_lnum;
- stacktrace_push_item(l, fp, NULL, lnum, filepath, filepath_alloced);
+ stacktrace_push_item(l, fp, NULL, lnum, filepath);
} else if (entry->es_type == ETYPE_AUCMD) {
const sctx_T sctx = entry->es_info.aucmd->script_ctx;
- bool filepath_alloced = false;
- char *filepath = sctx.sc_sid > 0 ? get_scriptname(sctx, &filepath_alloced) : "";
+ char *filepath = sctx.sc_sid > 0 ? get_scriptname(sctx, NULL) : "";
lnum += sctx.sc_lnum;
- stacktrace_push_item(l, NULL, entry->es_name, lnum, filepath, filepath_alloced);
+ stacktrace_push_item(l, NULL, entry->es_name, lnum, filepath);
}
}
return l;
@@ -2434,9 +2427,14 @@ void scriptnames_slash_adjust(void)
/// Get a pointer to a script name. Used for ":verbose set".
/// Message appended to "Last set from "
+///
+/// @param should_free if non-NULL and the script name is a file path, call
+/// home_replace_save() on it and set *should_free to true.
char *get_scriptname(sctx_T script_ctx, bool *should_free)
{
- *should_free = false;
+ if (should_free != NULL) {
+ *should_free = false;
+ }
switch (script_ctx.sc_sid) {
case SID_MODELINE:
@@ -2452,29 +2450,25 @@ char *get_scriptname(sctx_T script_ctx, bool *should_free)
case SID_WINLAYOUT:
return _("changed window size");
case SID_LUA:
- return _("Lua (run Nvim with -V1 for more details)");
+ return _("Lua");
case SID_API_CLIENT:
snprintf(IObuff, IOSIZE, _("API client (channel id %" PRIu64 ")"), script_ctx.sc_chan);
return IObuff;
case SID_STR:
return _("anonymous :source");
default: {
- scriptitem_T *const si = SCRIPT_ITEM(script_ctx.sc_sid);
- char *sname = si->sn_name;
+ char *const sname = SCRIPT_ITEM(script_ctx.sc_sid)->sn_name;
if (sname == NULL) {
snprintf(IObuff, IOSIZE, _("anonymous :source (script id %d)"),
script_ctx.sc_sid);
return IObuff;
}
-
- *should_free = true;
- sname = home_replace_save(NULL, sname);
- if (si->sn_lua && script_ctx.sc_lnum == 0) {
- char *const ret = concat_str(sname, _(" (run Nvim with -V1 for more details)"));
- xfree(sname);
- return ret;
+ if (should_free != NULL) {
+ *should_free = true;
+ return home_replace_save(NULL, sname);
+ } else {
+ return sname;
}
- return sname;
}
}
}