aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os/shell.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-30 20:35:25 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-30 20:35:25 +0000
commit1b7b916b7631ddf73c38e3a0070d64e4636cb2f3 (patch)
treecd08258054db80bb9a11b1061bb091c70b76926a /src/nvim/os/shell.c
parenteaa89c11d0f8aefbb512de769c6c82f61a8baca3 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.tar.gz
rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.tar.bz2
rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.zip
Merge remote-tracking branch 'upstream/master' into aucmd_textputpostaucmd_textputpost
Diffstat (limited to 'src/nvim/os/shell.c')
-rw-r--r--src/nvim/os/shell.c92
1 files changed, 53 insertions, 39 deletions
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c
index f1e2c5440f..191be784e8 100644
--- a/src/nvim/os/shell.c
+++ b/src/nvim/os/shell.c
@@ -1,6 +1,3 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
@@ -10,8 +7,7 @@
#include "auto/config.h"
#include "klib/kvec.h"
-#include "nvim/ascii.h"
-#include "nvim/buffer_defs.h"
+#include "nvim/ascii_defs.h"
#include "nvim/charset.h"
#include "nvim/eval.h"
#include "nvim/eval/typval_defs.h"
@@ -24,29 +20,30 @@
#include "nvim/event/wstream.h"
#include "nvim/ex_cmds.h"
#include "nvim/fileio.h"
+#include "nvim/func_attr.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
-#include "nvim/macros.h"
+#include "nvim/macros_defs.h"
#include "nvim/main.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/option_defs.h"
+#include "nvim/option_vars.h"
#include "nvim/os/fs.h"
-#include "nvim/os/os_defs.h"
#include "nvim/os/shell.h"
#include "nvim/os/signal.h"
#include "nvim/os/time.h"
#include "nvim/path.h"
-#include "nvim/pos.h"
+#include "nvim/pos_defs.h"
#include "nvim/profile.h"
#include "nvim/rbuffer.h"
+#include "nvim/state_defs.h"
#include "nvim/strings.h"
#include "nvim/tag.h"
-#include "nvim/types.h"
+#include "nvim/types_defs.h"
#include "nvim/ui.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
#define DYNAMIC_BUFFER_INIT { NULL, 0, 0 }
#define NS_1_SECOND 1000000000U // 1 second, in nanoseconds
@@ -134,6 +131,8 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
#define STYLE_VIMGLOB 2 // use "vimglob", for Posix sh
#define STYLE_PRINT 3 // use "print -N", for zsh
#define STYLE_BT 4 // `cmd` expansion, execute the pattern directly
+#define STYLE_GLOBSTAR 5 // use extended shell glob for bash (this uses extended
+ // globbing functionality with globstar, needs bash > 4)
int shell_style = STYLE_ECHO;
int check_spaces;
static bool did_find_nul = false;
@@ -141,10 +140,13 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
// vimglob() function to define for Posix shell
static char *sh_vimglob_func =
"vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >";
+ // vimglob() function with globstar setting enabled, only for bash >= 4.X
+ static char *sh_globstar_opt =
+ "[[ ${BASH_VERSINFO[0]} -ge 4 ]] && shopt -s globstar; ";
bool is_fish_shell =
#if defined(UNIX)
- strncmp((char *)invocation_path_tail(p_sh, NULL), "fish", 4) == 0;
+ strncmp(invocation_path_tail(p_sh, NULL), "fish", 4) == 0;
#else
false;
#endif
@@ -190,6 +192,8 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
// If we use *zsh, "print -N" will work better than "glob".
// STYLE_VIMGLOB: NL separated
// If we use *sh*, we define "vimglob()".
+ // STYLE_GLOBSTAR: NL separated
+ // If we use *bash*, we define "vimglob() and enable globstar option".
// STYLE_ECHO: space separated.
// A shell we don't know, stay safe and use "echo".
if (num_pat == 1 && *pat[0] == '`'
@@ -203,9 +207,12 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
shell_style = STYLE_PRINT;
}
}
- if (shell_style == STYLE_ECHO
- && strstr(path_tail(p_sh), "sh") != NULL) {
- shell_style = STYLE_VIMGLOB;
+ if (shell_style == STYLE_ECHO) {
+ if (strstr(path_tail(p_sh), "bash") != NULL) {
+ shell_style = STYLE_GLOBSTAR;
+ } else if (strstr(path_tail(p_sh), "sh") != NULL) {
+ shell_style = STYLE_VIMGLOB;
+ }
}
// Compute the length of the command. We need 2 extra bytes: for the
@@ -214,6 +221,8 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
len = strlen(tempname) + 29;
if (shell_style == STYLE_VIMGLOB) {
len += strlen(sh_vimglob_func);
+ } else if (shell_style == STYLE_GLOBSTAR) {
+ len += strlen(sh_vimglob_func) + strlen(sh_globstar_opt);
}
for (i = 0; i < num_pat; i++) {
@@ -281,6 +290,9 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
STRCAT(command, "print -N >");
} else if (shell_style == STYLE_VIMGLOB) {
STRCAT(command, sh_vimglob_func);
+ } else if (shell_style == STYLE_GLOBSTAR) {
+ STRCAT(command, sh_globstar_opt);
+ STRCAT(command, sh_vimglob_func);
} else {
STRCAT(command, "echo >");
}
@@ -352,7 +364,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
// When running in the background, give it some time to create the temp
// file, but don't wait for it to finish.
if (ampersand) {
- os_delay(10L, true);
+ os_delay(10, true);
}
xfree(command);
@@ -364,7 +376,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
if (!(flags & EW_SILENT)) {
msg_putchar('\n'); // clear bottom line quickly
cmdline_row = Rows - 1; // continue on last line
- msg(_(e_wildexpand));
+ msg(_(e_wildexpand), 0);
msg_start(); // don't overwrite this message
}
@@ -381,13 +393,13 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
if (fd == NULL) {
// Something went wrong, perhaps a file name with a special char.
if (!(flags & EW_SILENT)) {
- msg(_(e_wildexpand));
+ msg(_(e_wildexpand), 0);
msg_start(); // don't overwrite this message
}
xfree(tempname);
goto notfound;
}
- int fseek_res = fseek(fd, 0L, SEEK_END);
+ int fseek_res = fseek(fd, 0, SEEK_END);
if (fseek_res < 0) {
xfree(tempname);
fclose(fd);
@@ -399,11 +411,11 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
fclose(fd);
return FAIL;
}
-#if SIZEOF_LONG_LONG > SIZEOF_SIZE_T
- assert(templen <= (long long)SIZE_MAX); // NOLINT(runtime/int)
+#if 8 > SIZEOF_SIZE_T
+ assert(templen <= SIZE_MAX); // NOLINT(runtime/int)
#endif
len = (size_t)templen;
- fseek(fd, 0L, SEEK_SET);
+ fseek(fd, 0, SEEK_SET);
buffer = xmalloc(len + 1);
// fread() doesn't terminate buffer with NUL;
// appropriate termination (not always NUL) is done below.
@@ -430,7 +442,9 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
p = skipwhite(p); // skip to next entry
}
// file names are separated with NL
- } else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) {
+ } else if (shell_style == STYLE_BT
+ || shell_style == STYLE_VIMGLOB
+ || shell_style == STYLE_GLOBSTAR) {
buffer[len] = NUL; // make sure the buffer ends in NUL
p = buffer;
for (i = 0; *p != NUL; i++) { // count number of entries
@@ -496,7 +510,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in
(*file)[i] = p;
// Space or NL separates
if (shell_style == STYLE_ECHO || shell_style == STYLE_BT
- || shell_style == STYLE_VIMGLOB) {
+ || shell_style == STYLE_VIMGLOB || shell_style == STYLE_GLOBSTAR) {
while (!(shell_style == STYLE_ECHO && *p == ' ')
&& *p != '\n' && *p != NUL) {
p++;
@@ -715,7 +729,7 @@ int call_shell(char *cmd, ShellOpts opts, char *extra_shell_arg)
if (p_verbose > 3) {
verbose_enter();
- smsg(_("Executing command: \"%s\""), cmd == NULL ? p_sh : cmd);
+ smsg(0, _("Executing command: \"%s\""), cmd == NULL ? p_sh : cmd);
msg_putchar('\n');
verbose_leave();
}
@@ -786,9 +800,9 @@ char *get_cmd_output(char *cmd, char *infile, ShellOpts flags, size_t *ret_len)
goto done;
}
- fseek(fd, 0L, SEEK_END);
+ fseek(fd, 0, SEEK_END);
size_t len = (size_t)ftell(fd); // get size of temp file
- fseek(fd, 0L, SEEK_SET);
+ fseek(fd, 0, SEEK_SET);
buffer = xmalloc(len + 1);
size_t i = fread(buffer, 1, len, fd);
@@ -876,9 +890,9 @@ static int do_os_system(char **argv, const char *input, size_t len, char **outpu
// Failed, probably 'shell' is not executable.
if (!silent) {
msg_puts(_("\nshell failed to start: "));
- msg_outtrans((char *)os_strerror(status));
+ msg_outtrans(os_strerror(status), 0);
msg_puts(": ");
- msg_outtrans(prog);
+ msg_outtrans(prog, 0);
msg_putchar('\n');
}
multiqueue_free(events);
@@ -1006,9 +1020,9 @@ static void system_data_cb(Stream *stream, RBuffer *buf, size_t count, void *dat
/// Returns the previous decision if size=0.
static bool out_data_decide_throttle(size_t size)
{
- static uint64_t started = 0; // Start time of the current throttle.
- static size_t received = 0; // Bytes observed since last throttle.
- static size_t visit = 0; // "Pulse" count of the current throttle.
+ static uint64_t started = 0; // Start time of the current throttle.
+ static size_t received = 0; // Bytes observed since last throttle.
+ static size_t visit = 0; // "Pulse" count of the current throttle.
static char pulse_msg[] = { ' ', ' ', ' ', '\0' };
if (!size) {
@@ -1026,7 +1040,7 @@ static bool out_data_decide_throttle(size_t size)
started = os_hrtime();
} else {
uint64_t since = os_hrtime() - started;
- if (since < (visit * 0.1L * NS_1_SECOND)) {
+ if (since < (visit * (NS_1_SECOND / 10))) {
return true;
}
if (since > (3 * NS_1_SECOND)) {
@@ -1088,7 +1102,7 @@ static void out_data_ring(char *output, size_t size)
last_skipped_len = MAX_CHUNK_SIZE;
} else if (size > 0) {
// Length of the old data that can be kept.
- size_t keep_len = MIN(last_skipped_len, MAX_CHUNK_SIZE - size);
+ size_t keep_len = MIN(last_skipped_len, MAX_CHUNK_SIZE - size);
size_t keep_start = last_skipped_len - keep_len;
// Shift the kept part of the old data to the start.
if (keep_start) {
@@ -1127,7 +1141,7 @@ static void out_data_append_to_screen(char *output, size_t *count, bool eof)
goto end;
}
- (void)msg_outtrans_len_attr(p, i, 0);
+ (void)msg_outtrans_len(p, i, 0);
p += i;
}
}
@@ -1180,7 +1194,7 @@ static size_t tokenize(const char *const str, char **const argv)
}
argc++;
- p = (const char *)skipwhite((p + len));
+ p = skipwhite((p + len));
}
return argc;
@@ -1221,12 +1235,12 @@ static size_t word_length(const char *str)
/// before we finish writing.
static void read_input(DynamicBuffer *buf)
{
- size_t written = 0, l = 0, len = 0;
+ size_t written = 0, len = 0;
linenr_T lnum = curbuf->b_op_start.lnum;
char *lp = ml_get(lnum);
- for (;;) {
- l = strlen(lp + written);
+ while (true) {
+ size_t l = strlen(lp + written);
if (l == 0) {
len = 0;
} else if (lp[written] == NL) {