aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-01-29 03:36:47 +0300
committerZyX <kp-pav@yandex.ru>2017-03-27 00:12:42 +0300
commit3d48c35d6bfa83ba3ae621fa9ec3f512da199f59 (patch)
treedf801c433c2be1eb94aafefce914e24113b888fa
parent3531d8c8eaa6783637f510dbc5dbd58c9d435b61 (diff)
downloadrneovim-3d48c35d6bfa83ba3ae621fa9ec3f512da199f59.tar.gz
rneovim-3d48c35d6bfa83ba3ae621fa9ec3f512da199f59.tar.bz2
rneovim-3d48c35d6bfa83ba3ae621fa9ec3f512da199f59.zip
ex_getln: Refactor script_get()
1. Use `char *` for strings. 2. Add `const` qualifiers. 3. Add attributes and documentation. 4. Handle skipping *inside*. 5. Handle non-heredoc argument also inside: deferring this to the caller is pointless because all callers need the same thing. Though new ex_lua caller may live without allocations in this case, allocating nevertheless produces cleaner code. 6. Note that all callers call script_get with `eap` and `eap->arg`. Thus second argument is useless in practice: it is one and the same always and can be reached through the first argument.
-rw-r--r--src/nvim/ex_cmds2.c11
-rw-r--r--src/nvim/ex_docmd.c8
-rw-r--r--src/nvim/ex_getln.c68
-rw-r--r--src/nvim/viml/executor/executor.c9
4 files changed, 58 insertions, 38 deletions
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 9fc4ef2a02..092bb38dd0 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -3695,19 +3695,18 @@ char_u *get_locales(expand_T *xp, int idx)
static void script_host_execute(char *name, exarg_T *eap)
{
- uint8_t *script = script_get(eap, eap->arg);
+ size_t len;
+ char *const script = script_get(eap, &len);
- if (!eap->skip) {
- list_T *args = list_alloc();
+ if (script != NULL) {
+ list_T *const args = list_alloc();
// script
- list_append_string(args, script ? script : eap->arg, -1);
+ list_append_allocated_string(args, script);
// current range
list_append_number(args, (int)eap->line1);
list_append_number(args, (int)eap->line2);
(void)eval_call_provider(name, "execute", args);
}
-
- xfree(script);
}
static void script_host_execute_file(char *name, exarg_T *eap)
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index aa43b71a0d..74bb6177c6 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -3734,10 +3734,12 @@ void ex_ni(exarg_T *eap)
/// Skips over ":perl <<EOF" constructs.
static void ex_script_ni(exarg_T *eap)
{
- if (!eap->skip)
+ if (!eap->skip) {
ex_ni(eap);
- else
- xfree(script_get(eap, eap->arg));
+ } else {
+ size_t len;
+ xfree(script_get(eap, &len));
+ }
}
/*
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 58979c0e43..f7e10f3787 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -5343,47 +5343,61 @@ static int ex_window(void)
return cmdwin_result;
}
-/*
- * Used for commands that either take a simple command string argument, or:
- * cmd << endmarker
- * {script}
- * endmarker
- * Returns a pointer to allocated memory with {script} or NULL.
- */
-char_u *script_get(exarg_T *eap, char_u *cmd)
+/// Get script string
+///
+/// Used for commands which accept either `:command script` or
+///
+/// :command << endmarker
+/// script
+/// endmarker
+///
+/// @param eap Command being run.
+/// @param[out] lenp Location where length of resulting string is saved. Will
+/// be set to zero when skipping.
+///
+/// @return [allocated] NULL or script. Does not show any error messages.
+/// NULL is returned when skipping and on error.
+char *script_get(exarg_T *const eap, size_t *const lenp)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC
{
- char_u *theline;
- char *end_pattern = NULL;
- char dot[] = ".";
- garray_T ga;
+ const char *const cmd = (const char *)eap->arg;
- if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL)
- return NULL;
-
- ga_init(&ga, 1, 0x400);
+ if (cmd[0] != '<' || cmd[1] != '<' || eap->getline == NULL) {
+ *lenp = STRLEN(eap->arg);
+ return xmemdupz(eap->arg, *lenp);
+ }
- if (cmd[2] != NUL)
- end_pattern = (char *)skipwhite(cmd + 2);
- else
- end_pattern = dot;
+ garray_T ga = { .ga_data = NULL, .ga_len = 0 };
+ if (!eap->skip) {
+ ga_init(&ga, 1, 0x400);
+ }
- for (;; ) {
- theline = eap->getline(
+ const char *const end_pattern = (
+ cmd[2] != NUL
+ ? (const char *)skipwhite((const char_u *)cmd + 2)
+ : ".");
+ for (;;) {
+ char *const theline = (char *)eap->getline(
eap->cstack->cs_looplevel > 0 ? -1 :
NUL, eap->cookie, 0);
- if (theline == NULL || STRCMP(end_pattern, theline) == 0) {
+ if (theline == NULL || strcmp(end_pattern, theline) == 0) {
xfree(theline);
break;
}
- ga_concat(&ga, theline);
- ga_append(&ga, '\n');
+ if (!eap->skip) {
+ ga_concat(&ga, (const char_u *)theline);
+ ga_append(&ga, '\n');
+ }
xfree(theline);
}
- ga_append(&ga, NUL);
+ *lenp = (size_t)ga.ga_len; // Set length without trailing NUL.
+ if (!eap->skip) {
+ ga_append(&ga, NUL);
+ }
- return (char_u *)ga.ga_data;
+ return (char *)ga.ga_data;
}
/// Iterate over history items
diff --git a/src/nvim/viml/executor/executor.c b/src/nvim/viml/executor/executor.c
index 38e3cf1c6d..fb39716f5c 100644
--- a/src/nvim/viml/executor/executor.c
+++ b/src/nvim/viml/executor/executor.c
@@ -277,9 +277,14 @@ void executor_eval_lua(const String str, typval_T *const arg,
void ex_lua(exarg_T *const eap)
FUNC_ATTR_NONNULL_ALL
{
- char *const code = (char *)script_get(eap, eap->arg);
+ size_t len;
+ char *const code = script_get(eap, &len);
+ if (eap->skip) {
+ xfree(code);
+ return;
+ }
typval_T tv = { .v_type = VAR_UNKNOWN };
- executor_exec_lua(cstr_as_string(code), &tv);
+ executor_exec_lua((String) { .data = code, .size = len }, &tv);
clear_tv(&tv);
xfree(code);
}