Merge pull request #27398 from bfredl/arena2

refactor(api): use arena for more stuff
This commit is contained in:
bfredl
2024-02-10 12:07:37 +01:00
committed by GitHub
22 changed files with 188 additions and 172 deletions

View File

@@ -96,15 +96,15 @@
/// - "belowright": |:belowright|.
/// - "topleft": |:topleft|.
/// - "botright": |:botright|.
Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err)
Dict(cmd) nvim_parse_cmd(String str, Dict(empty) *opts, Arena *arena, Error *err)
FUNC_API_SINCE(10) FUNC_API_FAST
{
Dictionary result = ARRAY_DICT_INIT;
Dict(cmd) result = { 0 };
// Parse command line
exarg_T ea;
CmdParseInfo cmdinfo;
char *cmdline = string_to_cstr(str);
char *cmdline = arena_memdupz(arena, str.data, str.size);
const char *errormsg = NULL;
if (!parse_cmdline(cmdline, &ea, &cmdinfo, &errormsg)) {
@@ -124,22 +124,23 @@ Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err)
// otherwise split arguments by whitespace.
if (ea.argt & EX_NOSPC) {
if (*ea.arg != NUL) {
ADD(args, STRING_OBJ(cstrn_to_string(ea.arg, length)));
args = arena_array(arena, 1);
ADD_C(args, STRING_OBJ(cstrn_as_string(ea.arg, length)));
}
} else {
size_t end = 0;
size_t len = 0;
char *buf = xcalloc(length, sizeof(char));
char *buf = arena_alloc(arena, length + 1, false);
bool done = false;
args = arena_array(arena, uc_nargs_upper_bound(ea.arg, length));
while (!done) {
done = uc_split_args_iter(ea.arg, length, &end, buf, &len);
if (len > 0) {
ADD(args, STRING_OBJ(cstrn_to_string(buf, len)));
ADD_C(args, STRING_OBJ(cstrn_as_string(buf, len)));
buf += len + 1;
}
}
xfree(buf);
}
ucmd_T *cmd = NULL;
@@ -149,40 +150,32 @@ Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err)
cmd = USER_CMD_GA(&curbuf->b_ucmds, ea.useridx);
}
if (cmd != NULL) {
PUT(result, "cmd", CSTR_TO_OBJ(cmd->uc_name));
} else {
PUT(result, "cmd", CSTR_TO_OBJ(get_command_name(NULL, ea.cmdidx)));
}
char *name = (cmd != NULL ? cmd->uc_name : get_command_name(NULL, ea.cmdidx));
PUT_KEY(result, cmd, cmd, cstr_as_string(name));
if (ea.argt & EX_RANGE) {
Array range = ARRAY_DICT_INIT;
Array range = arena_array(arena, 2);
if (ea.addr_count > 0) {
if (ea.addr_count > 1) {
ADD(range, INTEGER_OBJ(ea.line1));
ADD_C(range, INTEGER_OBJ(ea.line1));
}
ADD(range, INTEGER_OBJ(ea.line2));
ADD_C(range, INTEGER_OBJ(ea.line2));
}
PUT(result, "range", ARRAY_OBJ(range));
PUT_KEY(result, cmd, range, range);
}
if (ea.argt & EX_COUNT) {
if (ea.addr_count > 0) {
PUT(result, "count", INTEGER_OBJ(ea.line2));
} else if (cmd != NULL) {
PUT(result, "count", INTEGER_OBJ(cmd->uc_def));
} else {
PUT(result, "count", INTEGER_OBJ(0));
}
Integer count = ea.addr_count > 0 ? ea.line2 : (cmd != NULL ? cmd->uc_def : 0);
PUT_KEY(result, cmd, count, count);
}
if (ea.argt & EX_REGSTR) {
char reg[2] = { (char)ea.regname, NUL };
PUT(result, "reg", CSTR_TO_OBJ(reg));
PUT_KEY(result, cmd, reg, CSTR_TO_ARENA_STR(arena, reg));
}
PUT(result, "bang", BOOLEAN_OBJ(ea.forceit));
PUT(result, "args", ARRAY_OBJ(args));
PUT_KEY(result, cmd, bang, ea.forceit);
PUT_KEY(result, cmd, args, args);
char nargs[2];
if (ea.argt & EX_EXTRA) {
@@ -201,9 +194,9 @@ Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err)
nargs[0] = '0';
}
nargs[1] = '\0';
PUT(result, "nargs", CSTR_TO_OBJ(nargs));
PUT_KEY(result, cmd, nargs, CSTR_TO_ARENA_OBJ(arena, nargs));
const char *addr;
char *addr;
switch (ea.addr_type) {
case ADDR_LINES:
addr = "line";
@@ -233,38 +226,37 @@ Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err)
addr = "?";
break;
}
PUT(result, "addr", CSTR_TO_OBJ(addr));
PUT(result, "nextcmd", CSTR_TO_OBJ(ea.nextcmd));
PUT_KEY(result, cmd, addr, CSTR_AS_OBJ(addr));
PUT_KEY(result, cmd, nextcmd, CSTR_AS_OBJ(ea.nextcmd));
Dictionary mods = ARRAY_DICT_INIT;
// TODO(bfredl): nested keydict would be nice..
Dictionary mods = arena_dict(arena, 20);
Dictionary filter = ARRAY_DICT_INIT;
PUT(filter, "pattern", cmdinfo.cmdmod.cmod_filter_pat
? CSTR_TO_OBJ(cmdinfo.cmdmod.cmod_filter_pat)
: STATIC_CSTR_TO_OBJ(""));
PUT(filter, "force", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_filter_force));
PUT(mods, "filter", DICTIONARY_OBJ(filter));
Dictionary filter = arena_dict(arena, 2);
PUT_C(filter, "pattern", CSTR_TO_ARENA_OBJ(arena, cmdinfo.cmdmod.cmod_filter_pat));
PUT_C(filter, "force", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_filter_force));
PUT_C(mods, "filter", DICTIONARY_OBJ(filter));
PUT(mods, "silent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_SILENT));
PUT(mods, "emsg_silent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_ERRSILENT));
PUT(mods, "unsilent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_UNSILENT));
PUT(mods, "sandbox", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_SANDBOX));
PUT(mods, "noautocmd", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_NOAUTOCMD));
PUT(mods, "tab", INTEGER_OBJ(cmdinfo.cmdmod.cmod_tab - 1));
PUT(mods, "verbose", INTEGER_OBJ(cmdinfo.cmdmod.cmod_verbose - 1));
PUT(mods, "browse", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_BROWSE));
PUT(mods, "confirm", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_CONFIRM));
PUT(mods, "hide", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_HIDE));
PUT(mods, "keepalt", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPALT));
PUT(mods, "keepjumps", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPJUMPS));
PUT(mods, "keepmarks", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPMARKS));
PUT(mods, "keeppatterns", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPPATTERNS));
PUT(mods, "lockmarks", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_LOCKMARKS));
PUT(mods, "noswapfile", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_NOSWAPFILE));
PUT(mods, "vertical", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_split & WSP_VERT));
PUT(mods, "horizontal", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_split & WSP_HOR));
PUT_C(mods, "silent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_SILENT));
PUT_C(mods, "emsg_silent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_ERRSILENT));
PUT_C(mods, "unsilent", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_UNSILENT));
PUT_C(mods, "sandbox", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_SANDBOX));
PUT_C(mods, "noautocmd", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_NOAUTOCMD));
PUT_C(mods, "tab", INTEGER_OBJ(cmdinfo.cmdmod.cmod_tab - 1));
PUT_C(mods, "verbose", INTEGER_OBJ(cmdinfo.cmdmod.cmod_verbose - 1));
PUT_C(mods, "browse", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_BROWSE));
PUT_C(mods, "confirm", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_CONFIRM));
PUT_C(mods, "hide", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_HIDE));
PUT_C(mods, "keepalt", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPALT));
PUT_C(mods, "keepjumps", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPJUMPS));
PUT_C(mods, "keepmarks", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPMARKS));
PUT_C(mods, "keeppatterns", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_KEEPPATTERNS));
PUT_C(mods, "lockmarks", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_LOCKMARKS));
PUT_C(mods, "noswapfile", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_flags & CMOD_NOSWAPFILE));
PUT_C(mods, "vertical", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_split & WSP_VERT));
PUT_C(mods, "horizontal", BOOLEAN_OBJ(cmdinfo.cmdmod.cmod_split & WSP_HOR));
const char *split;
char *split;
if (cmdinfo.cmdmod.cmod_split & WSP_BOT) {
split = "botright";
} else if (cmdinfo.cmdmod.cmod_split & WSP_TOP) {
@@ -276,18 +268,17 @@ Dictionary nvim_parse_cmd(String str, Dict(empty) *opts, Error *err)
} else {
split = "";
}
PUT(mods, "split", CSTR_TO_OBJ(split));
PUT_C(mods, "split", CSTR_AS_OBJ(split));
PUT(result, "mods", DICTIONARY_OBJ(mods));
PUT_KEY(result, cmd, mods, mods);
Dictionary magic = ARRAY_DICT_INIT;
PUT(magic, "file", BOOLEAN_OBJ(cmdinfo.magic.file));
PUT(magic, "bar", BOOLEAN_OBJ(cmdinfo.magic.bar));
PUT(result, "magic", DICTIONARY_OBJ(magic));
Dictionary magic = arena_dict(arena, 2);
PUT_C(magic, "file", BOOLEAN_OBJ(cmdinfo.magic.file));
PUT_C(magic, "bar", BOOLEAN_OBJ(cmdinfo.magic.bar));
PUT_KEY(result, cmd, magic, magic);
undo_cmdmod(&cmdinfo.cmdmod);
end:
xfree(cmdline);
return result;
}

View File

@@ -514,11 +514,11 @@ static int64_t convert_index(int64_t index)
/// @param name Option name
/// @param[out] err Error details, if any
/// @return Option Information
Dictionary nvim_get_option_info(String name, Error *err)
Dictionary nvim_get_option_info(String name, Arena *arena, Error *err)
FUNC_API_SINCE(7)
FUNC_API_DEPRECATED_SINCE(11)
{
return get_vimoption(name, OPT_GLOBAL, curbuf, curwin, err);
return get_vimoption(name, OPT_GLOBAL, curbuf, curwin, arena, err);
}
/// Sets the global value of an option.

View File

@@ -263,10 +263,10 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict(
/// @see |nvim_get_commands()|
///
/// @return dictionary of all options
Dictionary nvim_get_all_options_info(Error *err)
Dictionary nvim_get_all_options_info(Arena *arena, Error *err)
FUNC_API_SINCE(7)
{
return get_all_vimoptions();
return get_all_vimoptions(arena);
}
/// Gets the option information for one option from arbitrary buffer or window
@@ -302,7 +302,7 @@ Dictionary nvim_get_all_options_info(Error *err)
/// Implies {scope} is "local".
/// @param[out] err Error details, if any
/// @return Option Information
Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err)
Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Arena *arena, Error *err)
FUNC_API_SINCE(11)
{
OptIndex opt_idx = 0;
@@ -317,5 +317,5 @@ Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err)
buf_T *buf = (req_scope == kOptReqBuf) ? (buf_T *)from : curbuf;
win_T *win = (req_scope == kOptReqWin) ? (win_T *)from : curwin;
return get_vimoption(name, scope, buf, win, err);
return get_vimoption(name, scope, buf, win, arena, err);
}

View File

@@ -425,12 +425,12 @@ String cstrn_as_string(char *str, size_t maxsize)
/// @param str the C string to use
/// @return The resulting String, or an empty String if
/// str was NULL
String cstr_as_string(char *str) FUNC_ATTR_PURE
String cstr_as_string(const char *str) FUNC_ATTR_PURE
{
if (str == NULL) {
return (String)STRING_INIT;
}
return (String){ .data = str, .size = strlen(str) };
return (String){ .data = (char *)str, .size = strlen(str) };
}
/// Return the owned memory of a ga as a String

View File

@@ -32,7 +32,8 @@
#define CSTR_AS_OBJ(s) STRING_OBJ(cstr_as_string(s))
#define CSTR_TO_OBJ(s) STRING_OBJ(cstr_to_string(s))
#define CSTR_TO_ARENA_OBJ(arena, s) STRING_OBJ(arena_string(arena, cstr_as_string(s)))
#define CSTR_TO_ARENA_STR(arena, s) arena_string(arena, cstr_as_string(s))
#define CSTR_TO_ARENA_OBJ(arena, s) STRING_OBJ(CSTR_TO_ARENA_STR(arena, s))
#define BUFFER_OBJ(s) ((Object) { \
.type = kObjectTypeBuffer, \

View File

@@ -247,10 +247,9 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictiona
void ui_attach(uint64_t channel_id, Integer width, Integer height, Boolean enable_rgb, Error *err)
FUNC_API_DEPRECATED_SINCE(1)
{
Dictionary opts = ARRAY_DICT_INIT;
PUT(opts, "rgb", BOOLEAN_OBJ(enable_rgb));
MAXSIZE_TEMP_DICT(opts, 1);
PUT_C(opts, "rgb", BOOLEAN_OBJ(enable_rgb));
nvim_ui_attach(channel_id, width, height, opts, err);
api_free_dictionary(opts);
}
/// Tells the nvim server if focus was gained or lost by the GUI
@@ -789,7 +788,7 @@ void remote_ui_hl_attr_define(UI *ui, Integer id, HlAttrs rgb_attrs, HlAttrs cte
// system. So we add them here.
if (rgb_attrs.url >= 0) {
const char *url = hl_get_url((uint32_t)rgb_attrs.url);
PUT_C(rgb, "url", STRING_OBJ(cstr_as_string((char *)url)));
PUT_C(rgb, "url", CSTR_AS_OBJ(url));
}
ADD_C(args, DICTIONARY_OBJ(rgb));
@@ -857,7 +856,7 @@ void remote_ui_put(UI *ui, const char *cell)
UIData *data = ui->data;
data->client_col++;
Array args = data->call_buf;
ADD_C(args, CSTR_AS_OBJ((char *)cell));
ADD_C(args, CSTR_AS_OBJ(cell));
push_call(ui, "put", args);
}
@@ -1113,9 +1112,3 @@ void remote_ui_event(UI *ui, char *name, Array args)
free_ret:
arena_mem_free(arena_finish(&arena));
}
void remote_ui_inspect(UI *ui, Dictionary *info)
{
UIData *data = ui->data;
PUT(*info, "chan", INTEGER_OBJ((Integer)data->channel_id));
}

View File

@@ -1866,10 +1866,10 @@ Dictionary nvim__stats(Arena *arena)
/// - "rgb" true if the UI uses RGB colors (false implies |cterm-colors|)
/// - "ext_..." Requested UI extensions, see |ui-option|
/// - "chan" |channel-id| of remote UI
Array nvim_list_uis(void)
Array nvim_list_uis(Arena *arena)
FUNC_API_SINCE(4)
{
return ui_array();
return ui_array(arena);
}
/// Gets the immediate children of process `pid`.
@@ -2005,7 +2005,7 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Arena *arena, E
ADD_C(ret, DICTIONARY_OBJ(hl_get_attr_by_id(attr, true, arena, err)));
// will not work first time
if (!highlight_use_hlstate()) {
ADD_C(ret, ARRAY_OBJ(hl_inspect(attr)));
ADD_C(ret, ARRAY_OBJ(hl_inspect(attr, arena)));
}
return ret;
}
@@ -2289,7 +2289,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena *
opts->use_winbar, stc_hl_id);
PUT_C(hl_info, "start", INTEGER_OBJ(0));
PUT_C(hl_info, "group", CSTR_AS_OBJ((char *)grpname));
PUT_C(hl_info, "group", CSTR_AS_OBJ(grpname));
ADD_C(hl_values, DICTIONARY_OBJ(hl_info));
}
@@ -2308,7 +2308,7 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena *
snprintf(user_group, sizeof(user_group), "User%d", sp->userhl);
grpname = arena_memdupz(arena, user_group, strlen(user_group));
}
PUT_C(hl_info, "group", CSTR_AS_OBJ((char *)grpname));
PUT_C(hl_info, "group", CSTR_AS_OBJ(grpname));
ADD_C(hl_values, DICTIONARY_OBJ(hl_info));
}
PUT_C(result, "highlights", ARRAY_OBJ(hl_values));

View File

@@ -626,7 +626,7 @@ Dict(win_config) nvim_win_get_config(Window window, Arena *arena, Error *err)
PUT_KEY_X(rv, bufpos, pos);
}
}
PUT_KEY_X(rv, anchor, cstr_as_string((char *)float_anchor_str[config->anchor]));
PUT_KEY_X(rv, anchor, cstr_as_string(float_anchor_str[config->anchor]));
PUT_KEY_X(rv, row, config->row);
PUT_KEY_X(rv, col, config->col);
PUT_KEY_X(rv, zindex, config->zindex);
@@ -659,12 +659,12 @@ Dict(win_config) nvim_win_get_config(Window window, Arena *arena, Error *err)
PUT_KEY_X(rv, width, wp->w_width);
PUT_KEY_X(rv, height, wp->w_height);
WinSplit split = win_split_dir(wp);
PUT_KEY_X(rv, split, cstr_as_string((char *)win_split_str[split]));
PUT_KEY_X(rv, split, cstr_as_string(win_split_str[split]));
}
const char *rel = (wp->w_floating && !config->external
? float_relative_str[config->relative] : "");
PUT_KEY_X(rv, relative, cstr_as_string((char *)rel));
PUT_KEY_X(rv, relative, cstr_as_string(rel));
return rv;
}