mirror of
https://github.com/neovim/neovim.git
synced 2025-09-12 06:18:16 +00:00
refactor(eval): use arena when converting typvals to Object
Note: this contains two _temporary_ changes which can be reverted once the Arena vs no-Arena distinction in API wrappers has been removed. Both nlua_push_Object and object_to_vim_take_luaref() has been changed to take the object argument as a pointer. This is not going to be necessary once these are only used with arena (or not at all) allocated Objects. The object_to_vim() variant which leaves luaref untouched might need to stay for a little longer.
This commit is contained in:
@@ -305,7 +305,7 @@ end:
|
||||
/// - output: (boolean, default false) Whether to return command output.
|
||||
/// @param[out] err Error details, if any.
|
||||
/// @return Command output (non-error, non-shell |:!|) if `output` is true, else empty string.
|
||||
String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error *err)
|
||||
String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Arena *arena, Error *err)
|
||||
FUNC_API_SINCE(10)
|
||||
{
|
||||
exarg_T ea;
|
||||
@@ -343,7 +343,7 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
|
||||
goto end;
|
||||
});
|
||||
|
||||
cmdname = string_to_cstr(cmd->cmd);
|
||||
cmdname = arena_string(arena, cmd->cmd).data;
|
||||
ea.cmd = cmdname;
|
||||
|
||||
char *p = find_ex_command(&ea, NULL);
|
||||
@@ -352,9 +352,8 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
|
||||
// autocommands defined, trigger the matching autocommands.
|
||||
if (p != NULL && ea.cmdidx == CMD_SIZE && ASCII_ISUPPER(*ea.cmd)
|
||||
&& has_event(EVENT_CMDUNDEFINED)) {
|
||||
p = xstrdup(cmdname);
|
||||
p = arena_string(arena, cmd->cmd).data;
|
||||
int ret = apply_autocmds(EVENT_CMDUNDEFINED, p, p, true, NULL);
|
||||
xfree(p);
|
||||
// If the autocommands did something and didn't cause an error, try
|
||||
// finding the command again.
|
||||
p = (ret && !aborting()) ? find_ex_command(&ea, NULL) : ea.cmd;
|
||||
@@ -383,28 +382,31 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
|
||||
if (HAS_KEY(cmd, cmd, args)) {
|
||||
// Process all arguments. Convert non-String arguments to String and check if String arguments
|
||||
// have non-whitespace characters.
|
||||
args = arena_array(arena, cmd->args.size);
|
||||
for (size_t i = 0; i < cmd->args.size; i++) {
|
||||
Object elem = cmd->args.items[i];
|
||||
char *data_str;
|
||||
|
||||
switch (elem.type) {
|
||||
case kObjectTypeBoolean:
|
||||
data_str = xcalloc(2, sizeof(char));
|
||||
data_str = arena_alloc(arena, 2, false);
|
||||
data_str[0] = elem.data.boolean ? '1' : '0';
|
||||
data_str[1] = '\0';
|
||||
ADD_C(args, CSTR_AS_OBJ(data_str));
|
||||
break;
|
||||
case kObjectTypeBuffer:
|
||||
case kObjectTypeWindow:
|
||||
case kObjectTypeTabpage:
|
||||
case kObjectTypeInteger:
|
||||
data_str = xcalloc(NUMBUFLEN, sizeof(char));
|
||||
data_str = arena_alloc(arena, NUMBUFLEN, false);
|
||||
snprintf(data_str, NUMBUFLEN, "%" PRId64, elem.data.integer);
|
||||
ADD_C(args, CSTR_AS_OBJ(data_str));
|
||||
break;
|
||||
case kObjectTypeString:
|
||||
VALIDATE_EXP(!string_iswhite(elem.data.string), "command arg", "non-whitespace", NULL, {
|
||||
goto end;
|
||||
});
|
||||
data_str = string_to_cstr(elem.data.string);
|
||||
ADD_C(args, elem);
|
||||
break;
|
||||
default:
|
||||
VALIDATE_EXP(false, "command arg", "valid type", api_typename(elem.type), {
|
||||
@@ -412,8 +414,6 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
ADD(args, CSTR_AS_OBJ(data_str));
|
||||
}
|
||||
|
||||
bool argc_valid;
|
||||
@@ -666,26 +666,20 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
|
||||
}
|
||||
|
||||
if (opts->output && capture_local.ga_len > 1) {
|
||||
retv = (String){
|
||||
.data = capture_local.ga_data,
|
||||
.size = (size_t)capture_local.ga_len,
|
||||
};
|
||||
// TODO(bfredl): if there are more cases like this we might want custom xfree-list in arena
|
||||
retv = CBUF_TO_ARENA_STR(arena, capture_local.ga_data, (size_t)capture_local.ga_len);
|
||||
// redir usually (except :echon) prepends a newline.
|
||||
if (retv.data[0] == '\n') {
|
||||
memmove(retv.data, retv.data + 1, retv.size - 1);
|
||||
retv.data[retv.size - 1] = '\0';
|
||||
retv.size = retv.size - 1;
|
||||
retv.data++;
|
||||
retv.size--;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
clear_ga:
|
||||
if (opts->output) {
|
||||
ga_clear(&capture_local);
|
||||
}
|
||||
end:
|
||||
api_free_array(args);
|
||||
xfree(cmdline);
|
||||
xfree(cmdname);
|
||||
xfree(ea.args);
|
||||
xfree(ea.arglens);
|
||||
|
||||
|
Reference in New Issue
Block a user