aboutsummaryrefslogtreecommitdiff
path: root/src/nvim
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2022-10-08 15:48:07 +0100
committerLewis Russell <lewis6991@gmail.com>2022-10-13 16:37:23 +0100
commit288208257c8d6b3c8dcce7ee6c7b6c7bb7bafb27 (patch)
tree8a4d8f0d54a98d87bb219f54def43a5f0aa5d402 /src/nvim
parenteb123b565e201418dd135d2602dc20eea3cead39 (diff)
downloadrneovim-288208257c8d6b3c8dcce7ee6c7b6c7bb7bafb27.tar.gz
rneovim-288208257c8d6b3c8dcce7ee6c7b6c7bb7bafb27.tar.bz2
rneovim-288208257c8d6b3c8dcce7ee6c7b6c7bb7bafb27.zip
feat(cscope)!: remove
Diffstat (limited to 'src/nvim')
-rw-r--r--src/nvim/cmdexpand.c12
-rw-r--r--src/nvim/eval.lua1
-rw-r--r--src/nvim/eval/funcs.c25
-rw-r--r--src/nvim/ex_cmds.lua24
-rw-r--r--src/nvim/ex_docmd.c5
-rwxr-xr-xsrc/nvim/generators/gen_declarations.lua3
-rw-r--r--src/nvim/if_cscope.c2027
-rw-r--r--src/nvim/if_cscope.h10
-rw-r--r--src/nvim/if_cscope_defs.h64
-rw-r--r--src/nvim/main.c2
-rw-r--r--src/nvim/normal.c6
-rw-r--r--src/nvim/option_defs.h9
-rw-r--r--src/nvim/options.lua52
-rw-r--r--src/nvim/optionstr.c17
-rw-r--r--src/nvim/tag.c226
-rw-r--r--src/nvim/tag.h2
-rw-r--r--src/nvim/testdir/test_cscope.vim344
-rw-r--r--src/nvim/usercmd.c1
-rw-r--r--src/nvim/vim.h1
19 files changed, 89 insertions, 2742 deletions
diff --git a/src/nvim/cmdexpand.c b/src/nvim/cmdexpand.c
index a29d022606..e728bd6967 100644
--- a/src/nvim/cmdexpand.c
+++ b/src/nvim/cmdexpand.c
@@ -22,7 +22,6 @@
#include "nvim/getchar.h"
#include "nvim/help.h"
#include "nvim/highlight_group.h"
-#include "nvim/if_cscope.h"
#include "nvim/locale.h"
#include "nvim/lua/executor.h"
#include "nvim/mapping.h"
@@ -1419,11 +1418,6 @@ static const char *set_context_by_cmdname(const char *cmd, cmdidx_T cmdidx, cons
case CMD_highlight:
set_context_in_highlight_cmd(xp, arg);
break;
- case CMD_cscope:
- case CMD_lcscope:
- case CMD_scscope:
- set_context_in_cscope_cmd(xp, arg, cmdidx);
- break;
case CMD_sign:
set_context_in_sign_cmd(xp, (char *)arg);
break;
@@ -2063,7 +2057,6 @@ static int ExpandOther(expand_T *xp, regmatch_T *rmp, int *num_file, char ***fil
{ EXPAND_HIGHLIGHT, (ExpandFunc)get_highlight_name, true, false },
{ EXPAND_EVENTS, expand_get_event_name, true, false },
{ EXPAND_AUGROUP, expand_get_augroup_name, true, false },
- { EXPAND_CSCOPE, get_cscope_name, true, true },
{ EXPAND_SIGN, get_sign_name, true, true },
{ EXPAND_PROFILE, get_profile_name, true, true },
#ifdef HAVE_WORKING_LIBINTL
@@ -2883,11 +2876,6 @@ void f_getcompletion(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
xpc.xp_pattern_len = strlen(xpc.xp_pattern);
}
- if (xpc.xp_context == EXPAND_CSCOPE) {
- set_context_in_cscope_cmd(&xpc, (const char *)xpc.xp_pattern, CMD_cscope);
- xpc.xp_pattern_len = strlen(xpc.xp_pattern);
- }
-
if (xpc.xp_context == EXPAND_SIGN) {
set_context_in_sign_cmd(&xpc, xpc.xp_pattern);
xpc.xp_pattern_len = strlen(xpc.xp_pattern);
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 837fef23f4..cc26bbf1a8 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -88,7 +88,6 @@ return {
cos={args=1, base=1, float_func="cos"},
cosh={args=1, base=1, float_func="cosh"},
count={args={2, 4}, base=1},
- cscope_connection={args={0, 3}},
ctxget={args={0, 1}},
ctxpop={},
ctxpush={args={0, 1}},
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index a326c44371..861f68993a 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -39,7 +39,6 @@
#include "nvim/getchar.h"
#include "nvim/globals.h"
#include "nvim/highlight_group.h"
-#include "nvim/if_cscope.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
#include "nvim/input.h"
@@ -1132,29 +1131,6 @@ static void f_count(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
rettv->vval.v_number = n;
}
-/// "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
-///
-/// Checks the existence of a cscope connection.
-static void f_cscope_connection(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
-{
- int num = 0;
- const char *dbpath = NULL;
- const char *prepend = NULL;
- char buf[NUMBUFLEN];
-
- if (argvars[0].v_type != VAR_UNKNOWN
- && argvars[1].v_type != VAR_UNKNOWN) {
- num = (int)tv_get_number(&argvars[0]);
- dbpath = tv_get_string(&argvars[1]);
- if (argvars[2].v_type != VAR_UNKNOWN) {
- prepend = tv_get_string_buf(&argvars[2], buf);
- }
- }
-
- rettv->vval.v_number = cs_connection(num, (char_u *)dbpath,
- (char_u *)prepend);
-}
-
/// "ctxget([{index}])" function
static void f_ctxget(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
{
@@ -3565,7 +3541,6 @@ static void f_has(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
"cmdwin",
"comments",
"conceal",
- "cscope",
"cursorbind",
"cursorshape",
#ifdef DEBUG
diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua
index 04b8832428..e3eea884c4 100644
--- a/src/nvim/ex_cmds.lua
+++ b/src/nvim/ex_cmds.lua
@@ -673,18 +673,6 @@ module.cmds = {
func='ex_cc',
},
{
- command='cscope',
- flags=bit.bor(EXTRA, NOTRLCOM, XFILE),
- addr_type='ADDR_NONE',
- func='ex_cscope',
- },
- {
- command='cstag',
- flags=bit.bor(BANG, TRLBAR, WORD1),
- addr_type='ADDR_NONE',
- func='ex_cstag',
- },
- {
command='cunmap',
flags=bit.bor(EXTRA, TRLBAR, NOTRLCOM, CTRLV, CMDWIN, LOCK_OK),
addr_type='ADDR_NONE',
@@ -1405,12 +1393,6 @@ module.cmds = {
func='ex_cclose',
},
{
- command='lcscope',
- flags=bit.bor(EXTRA, NOTRLCOM, XFILE),
- addr_type='ADDR_NONE',
- func='ex_cscope',
- },
- {
command='ldo',
flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM, RANGE, DFLALL),
addr_type='ADDR_QUICKFIX_VALID',
@@ -2422,12 +2404,6 @@ module.cmds = {
func='ex_scriptencoding',
},
{
- command='scscope',
- flags=bit.bor(EXTRA, NOTRLCOM),
- addr_type='ADDR_NONE',
- func='ex_scscope',
- },
- {
command='set',
flags=bit.bor(BANG, TRLBAR, EXTRA, CMDWIN, LOCK_OK, SBOXOK),
addr_type='ADDR_NONE',
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 5591b5f55d..77d310e338 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -44,7 +44,6 @@
#include "nvim/hardcopy.h"
#include "nvim/help.h"
#include "nvim/highlight_group.h"
-#include "nvim/if_cscope.h"
#include "nvim/input.h"
#include "nvim/keycodes.h"
#include "nvim/locale.h"
@@ -6589,10 +6588,6 @@ static void ex_tag_cmd(exarg_T *eap, char *name)
cmd = DT_LAST; // ":tlast"
break;
default: // ":tag"
- if (p_cst && *eap->arg != NUL) {
- ex_cstag(eap);
- return;
- }
cmd = DT_TAG;
break;
}
diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua
index bf1adaeee3..4097ff7dc5 100755
--- a/src/nvim/generators/gen_declarations.lua
+++ b/src/nvim/generators/gen_declarations.lua
@@ -182,8 +182,7 @@ Additionally uses the following environment variables:
If set to 1 then all generated declarations receive a comment with file
name and line number after the declaration. This may be useful for
debugging gen_declarations script, but not much beyond that with
- configured development environment (i.e. with ctags/cscope/finding
- definitions with clang/etc).
+ configured development environment (i.e. with with clang/etc).
WARNING: setting this to 1 will cause extensive rebuilds: declarations
generator script will not regenerate non-static.h file if its
diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c
deleted file mode 100644
index bc31d702f4..0000000000
--- a/src/nvim/if_cscope.c
+++ /dev/null
@@ -1,2027 +0,0 @@
-// 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
-
-// CSCOPE support for Vim added by Andy Kahn <kahn@zk3.dec.com>
-// Ported to Win32 by Sergey Khorev <sergey.khorev@gmail.com>
-//
-// The basic idea/structure of cscope for Vim was borrowed from Nvi. There
-// might be a few lines of code that look similar to what Nvi has.
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <stdbool.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "nvim/ascii.h"
-#include "nvim/autocmd.h"
-#include "nvim/buffer.h"
-#include "nvim/charset.h"
-#include "nvim/eval.h"
-#include "nvim/event/stream.h"
-#include "nvim/ex_eval.h"
-#include "nvim/fileio.h"
-#include "nvim/if_cscope.h"
-#include "nvim/memory.h"
-#include "nvim/message.h"
-#include "nvim/os/input.h"
-#include "nvim/os/os.h"
-#include "nvim/os/time.h"
-#include "nvim/path.h"
-#include "nvim/quickfix.h"
-#include "nvim/strings.h"
-#include "nvim/tag.h"
-#include "nvim/window.h"
-#if defined(UNIX)
-# include <sys/wait.h>
-#endif
-#include "nvim/if_cscope_defs.h"
-
-#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "if_cscope.c.generated.h"
-#endif
-
-static csinfo_T *csinfo = NULL;
-static size_t csinfo_size = 0; // number of items allocated in csinfo[]
-
-static int eap_arg_len; // length of eap->arg, set in cs_lookup_cmd()
-static cscmd_T cs_cmds[] =
-{
- { "add", cs_add,
- N_("Add a new database"), "add file|dir [pre-path] [flags]", 0 },
- { "find", cs_find,
- N_("Query for a pattern"), "find a|c|d|e|f|g|i|s|t name", 1 },
- { "help", cs_help,
- N_("Show this message"), "help", 0 },
- { "kill", cs_kill,
- N_("Kill a connection"), "kill #", 0 },
- { "reset", cs_reset,
- N_("Reinit all connections"), "reset", 0 },
- { "show", cs_show,
- N_("Show connections"), "show", 0 },
- { NULL, NULL, NULL, NULL, 0 }
-};
-
-static void cs_usage_msg(csid_e x)
-{
- (void)semsg(_("E560: Usage: cs[cope] %s"), cs_cmds[(int)x].usage);
-}
-
-static enum {
- EXP_CSCOPE_SUBCMD, // expand ":cscope" sub-commands
- EXP_SCSCOPE_SUBCMD, // expand ":scscope" sub-commands
- EXP_CSCOPE_FIND, // expand ":cscope find" arguments
- EXP_CSCOPE_KILL, // expand ":cscope kill" arguments
-} expand_what;
-
-// Function given to ExpandGeneric() to obtain the cscope command
-// expansion.
-char *get_cscope_name(expand_T *xp, int idx)
-{
- int current_idx;
-
- switch (expand_what) {
- case EXP_CSCOPE_SUBCMD:
- // Complete with sub-commands of ":cscope":
- // add, find, help, kill, reset, show
- return cs_cmds[idx].name;
- case EXP_SCSCOPE_SUBCMD: {
- // Complete with sub-commands of ":scscope": same sub-commands as
- // ":cscope" but skip commands which don't support split windows
- int i;
- for (i = 0, current_idx = 0; cs_cmds[i].name != NULL; i++) {
- if (cs_cmds[i].cansplit) {
- if (current_idx++ == idx) {
- break;
- }
- }
- }
- return cs_cmds[i].name;
- }
- case EXP_CSCOPE_FIND: {
- const char *query_type[] =
- {
- "a", "c", "d", "e", "f", "g", "i", "s", "t", NULL
- };
-
- // Complete with query type of ":cscope find {query_type}".
- // {query_type} can be letters (c, d, ... a) or numbers (0, 1,
- // ..., 9) but only complete with letters, since numbers are
- // redundant.
- return (char *)query_type[idx];
- }
- case EXP_CSCOPE_KILL: {
- static char connection[5];
-
- // ":cscope kill" accepts connection numbers or partial names of
- // the pathname of the cscope database as argument. Only complete
- // with connection numbers. -1 can also be used to kill all
- // connections.
- size_t i;
- for (i = 0, current_idx = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname == NULL) {
- continue;
- }
- if (current_idx++ == idx) {
- vim_snprintf(connection, sizeof(connection), "%zu", i);
- return connection;
- }
- }
- return (current_idx == idx && idx > 0) ? "-1" : NULL;
- }
- default:
- return NULL;
- }
-}
-
-// Handle command line completion for :cscope command.
-void set_context_in_cscope_cmd(expand_T *xp, const char *arg, cmdidx_T cmdidx)
-{
- // Default: expand subcommands.
- xp->xp_context = EXPAND_CSCOPE;
- xp->xp_pattern = (char *)arg;
- expand_what = ((cmdidx == CMD_scscope)
- ? EXP_SCSCOPE_SUBCMD : EXP_CSCOPE_SUBCMD);
-
- // (part of) subcommand already typed
- if (*arg != NUL) {
- const char *p = (const char *)skiptowhite(arg);
- if (*p != NUL) { // Past first word.
- xp->xp_pattern = skipwhite(p);
- if (*skiptowhite(xp->xp_pattern) != NUL) {
- xp->xp_context = EXPAND_NOTHING;
- } else if (STRNICMP(arg, "add", p - arg) == 0) {
- xp->xp_context = EXPAND_FILES;
- } else if (STRNICMP(arg, "kill", p - arg) == 0) {
- expand_what = EXP_CSCOPE_KILL;
- } else if (STRNICMP(arg, "find", p - arg) == 0) {
- expand_what = EXP_CSCOPE_FIND;
- } else {
- xp->xp_context = EXPAND_NOTHING;
- }
- }
- }
-}
-
-/// Find the command, print help if invalid, and then call the corresponding
-/// command function.
-///
-/// @param make_split whether to split window
-static void do_cscope_general(exarg_T *eap, int make_split)
-{
- cscmd_T *cmdp;
-
- if ((cmdp = cs_lookup_cmd(eap)) == NULL) {
- cs_help(eap);
- return;
- }
-
- if (make_split) {
- if (!cmdp->cansplit) {
- (void)msg_puts(_("This cscope command does not support splitting the window.\n"));
- return;
- }
- postponed_split = -1;
- postponed_split_flags = cmdmod.cmod_split;
- postponed_split_tab = cmdmod.cmod_tab;
- }
-
- cmdp->func(eap);
-
- postponed_split_flags = 0;
- postponed_split_tab = 0;
-}
-
-/// Implementation of ":cscope" and ":lcscope"
-void ex_cscope(exarg_T *eap)
-{
- do_cscope_general(eap, false);
-}
-
-/// Implementation of ":scscope". Same as ex_cscope(), but splits window, too.
-void ex_scscope(exarg_T *eap)
-{
- do_cscope_general(eap, true);
-}
-
-/// Implementation of ":cstag"
-void ex_cstag(exarg_T *eap)
-{
- int ret = false;
-
- if (*eap->arg == NUL) {
- (void)emsg(_("E562: Usage: cstag <ident>"));
- return;
- }
-
- switch (p_csto) {
- case 0:
- if (cs_check_for_connections()) {
- ret = cs_find_common("g", eap->arg, eap->forceit, false,
- false, (char_u *)(*eap->cmdlinep));
- if (ret == false) {
- cs_free_tags();
- if (msg_col) {
- msg_putchar('\n');
- }
-
- if (cs_check_for_tags()) {
- ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, false);
- }
- }
- } else if (cs_check_for_tags()) {
- ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, false);
- }
- break;
- case 1:
- if (cs_check_for_tags()) {
- ret = do_tag(eap->arg, DT_JUMP, 0, eap->forceit, false);
- if (ret == false) {
- if (msg_col) {
- msg_putchar('\n');
- }
-
- if (cs_check_for_connections()) {
- ret = cs_find_common("g", eap->arg, eap->forceit,
- false, false, (char_u *)(*eap->cmdlinep));
- if (ret == false) {
- cs_free_tags();
- }
- }
- }
- } else if (cs_check_for_connections()) {
- ret = cs_find_common("g", eap->arg, eap->forceit, false,
- false, (char_u *)(*eap->cmdlinep));
- if (ret == false) {
- cs_free_tags();
- }
- }
- break;
- default:
- break;
- }
-
- if (!ret) {
- (void)emsg(_("E257: cstag: tag not found"));
- g_do_tagpreview = 0;
- }
-}
-
-/// This simulates a vim_fgets(), but for cscope, returns the next line
-/// from the cscope output. should only be called from find_tags()
-///
-/// @return true if eof, false otherwise
-bool cs_fgets(char_u *buf, int size)
- FUNC_ATTR_NONNULL_ALL
-{
- char *p;
-
- if ((p = cs_manage_matches(NULL, NULL, 0, Get)) == NULL) {
- return true;
- }
- STRLCPY(buf, p, size);
-
- return false;
-}
-
-/// Called only from do_tag(), when popping the tag stack.
-void cs_free_tags(void)
-{
- cs_manage_matches(NULL, NULL, 0, Free);
-}
-
-/// Called from do_tag().
-void cs_print_tags(void)
-{
- cs_manage_matches(NULL, NULL, 0, Print);
-}
-
-// "cscope_connection([{num} , {dbpath} [, {prepend}]])" function
-//
-// Checks for the existence of a |cscope| connection. If no
-// parameters are specified, then the function returns:
-//
-// 0, if cscope was not available (not compiled in), or if there
-// are no cscope connections; or
-// 1, if there is at least one cscope connection.
-//
-// If parameters are specified, then the value of {num}
-// determines how existence of a cscope connection is checked:
-//
-// {num} Description of existence check
-// ----- ------------------------------
-// 0 Same as no parameters (e.g., "cscope_connection()").
-// 1 Ignore {prepend}, and use partial string matches for
-// {dbpath}.
-// 2 Ignore {prepend}, and use exact string matches for
-// {dbpath}.
-// 3 Use {prepend}, use partial string matches for both
-// {dbpath} and {prepend}.
-// 4 Use {prepend}, use exact string matches for both
-// {dbpath} and {prepend}.
-//
-// Note: All string comparisons are case sensitive!
-bool cs_connection(int num, char_u *dbpath, char_u *ppath)
-{
- if (num < 0 || num > 4 || (num > 0 && !dbpath)) {
- return false;
- }
-
- for (size_t i = 0; i < csinfo_size; i++) {
- if (!csinfo[i].fname) {
- continue;
- }
- if (num == 0) {
- return true;
- }
- switch (num) {
- case 1:
- if (strstr(csinfo[i].fname, (char *)dbpath)) {
- return true;
- }
- break;
- case 2:
- if (strcmp(csinfo[i].fname, (char *)dbpath) == 0) {
- return true;
- }
- break;
- case 3:
- if (strstr(csinfo[i].fname, (char *)dbpath)
- && ((!ppath && !csinfo[i].ppath)
- || (ppath
- && csinfo[i].ppath
- && strstr(csinfo[i].ppath, (char *)ppath)))) {
- return true;
- }
- break;
- case 4:
- if ((strcmp(csinfo[i].fname, (char *)dbpath) == 0)
- && ((!ppath && !csinfo[i].ppath)
- || (ppath
- && csinfo[i].ppath
- && (strcmp(csinfo[i].ppath, (char *)ppath) == 0)))) {
- return true;
- }
- break;
- }
- }
-
- return false;
-} // cs_connection
-
-// PRIVATE functions
-// **************************************************************************
-
-/// Add cscope database or a directory name (to look for cscope.out)
-/// to the cscope connection list.
-static int cs_add(exarg_T *eap)
-{
- char *fname, *ppath, *flags = NULL;
-
- if ((fname = strtok((char *)NULL, (const char *)" ")) == NULL) {
- cs_usage_msg(Add);
- return CSCOPE_FAILURE;
- }
- if ((ppath = strtok((char *)NULL, (const char *)" ")) != NULL) {
- flags = strtok((char *)NULL, (const char *)" ");
- }
-
- return cs_add_common(fname, ppath, flags);
-}
-
-static void cs_stat_emsg(char *fname)
-{
- int err = errno;
- (void)semsg(_("E563: stat(%s) error: %d"), fname, err);
-}
-
-/// The common routine to add a new cscope connection. Called by
-/// cs_add() and cs_reset(). I really don't like to do this, but this
-/// routine uses a number of goto statements.
-///
-/// @param arg1 filename - may contain environment variables
-/// @param arg2 prepend path - may contain environment variables
-static int cs_add_common(char *arg1, char *arg2, char *flags)
-{
- char *fname = NULL;
- char *fname2 = NULL;
- char *ppath = NULL;
- size_t usedlen = 0;
- char *fbuf = NULL;
-
- // get the filename (arg1), expand it, and try to stat it
- fname = xmalloc(MAXPATHL + 1);
-
- expand_env(arg1, fname, MAXPATHL);
- size_t len = strlen(fname);
- fbuf = fname;
- (void)modify_fname(":p", false, &usedlen, &fname, &fbuf, &len);
- if (fname == NULL) {
- goto add_err;
- }
- fname = xstrnsave(fname, len);
- xfree(fbuf);
- FileInfo file_info;
- bool file_info_ok = os_fileinfo(fname, &file_info);
- if (!file_info_ok) {
-staterr:
- if (p_csverbose) {
- cs_stat_emsg(fname);
- }
- goto add_err;
- }
-
- // get the prepend path (arg2), expand it, and see if it exists
- if (arg2 != NULL) {
- ppath = xmalloc(MAXPATHL + 1);
- expand_env(arg2, ppath, MAXPATHL);
- if (!os_path_exists(ppath)) {
- goto staterr;
- }
- }
-
- int i;
- // if filename is a directory, append the cscope database name to it
- if (S_ISDIR(file_info.stat.st_mode)) {
- fname2 = (char *)xmalloc(strlen(CSCOPE_DBFILE) + strlen(fname) + 2);
-
- while (fname[strlen(fname) - 1] == '/'
- ) {
- fname[strlen(fname) - 1] = '\0';
- if (fname[0] == '\0') {
- break;
- }
- }
- if (fname[0] == '\0') {
- (void)sprintf(fname2, "/%s", CSCOPE_DBFILE);
- } else {
- (void)sprintf(fname2, "%s/%s", fname, CSCOPE_DBFILE);
- }
-
- file_info_ok = os_fileinfo(fname2, &file_info);
- if (!file_info_ok) {
- if (p_csverbose) {
- cs_stat_emsg(fname2);
- }
- goto add_err;
- }
-
- i = cs_insert_filelist(fname2, ppath, flags, &file_info);
- } else if (S_ISREG(file_info.stat.st_mode) || S_ISLNK(file_info.stat.st_mode)) {
- i = cs_insert_filelist(fname, ppath, flags, &file_info);
- } else {
- if (p_csverbose) {
- (void)semsg(_("E564: %s is not a directory or a valid cscope database"),
- fname);
- }
- goto add_err;
- }
-
- if (i != -1) {
- assert(i >= 0);
- if (cs_create_connection((size_t)i) == CSCOPE_FAILURE
- || cs_read_prompt((size_t)i) == CSCOPE_FAILURE) {
- cs_release_csp((size_t)i, true);
- goto add_err;
- }
-
- if (p_csverbose) {
- msg_clr_eos();
- (void)smsg_attr(HL_ATTR(HLF_R),
- _("Added cscope database %s"),
- csinfo[i].fname);
- }
- }
-
- xfree(fname);
- xfree(fname2);
- xfree(ppath);
- return CSCOPE_SUCCESS;
-
-add_err:
- xfree(fname2);
- xfree(fname);
- xfree(ppath);
- return CSCOPE_FAILURE;
-}
-
-static bool cs_check_for_connections(void)
-{
- return cs_cnt_connections() > 0;
-}
-
-static int cs_check_for_tags(void)
-{
- return p_tags[0] != NUL && curbuf->b_p_tags != NULL;
-}
-
-/// Count the number of cscope connections.
-static size_t cs_cnt_connections(void)
-{
- size_t cnt = 0;
-
- for (size_t i = 0; i < csinfo_size; i++) {
- if (csinfo[i].fname != NULL) {
- cnt++;
- }
- }
- return cnt;
-}
-
-/// @param idx connection index
-static void cs_reading_emsg(size_t idx)
-{
- semsg(_("E262: error reading cscope connection %" PRIu64), (uint64_t)idx);
-}
-
-#define CSREAD_BUFSIZE 2048
-/// Count the number of matches for a given cscope connection.
-static int cs_cnt_matches(size_t idx)
-{
- char *stok;
- int nlines = 0;
-
- char *buf = xmalloc(CSREAD_BUFSIZE);
- for (;;) {
- errno = 0;
- if (!fgets(buf, CSREAD_BUFSIZE, csinfo[idx].fr_fp)) {
- if (errno == EINTR) {
- continue;
- }
-
- if (feof(csinfo[idx].fr_fp)) {
- errno = EIO;
- }
-
- cs_reading_emsg(idx);
-
- xfree(buf);
- return CSCOPE_FAILURE;
- }
-
- // If the database is out of date, or there's some other problem,
- // cscope will output error messages before the number-of-lines output.
- // Display/discard any output that doesn't match what we want.
- // Accept "\S*cscope: X lines", also matches "mlcscope".
- // Bail out for the "Unable to search" error.
- if (strstr((const char *)buf, "Unable to search database") != NULL) {
- break;
- }
- if ((stok = strtok(buf, (const char *)" ")) == NULL) {
- continue;
- }
- if (strstr((const char *)stok, "cscope:") == NULL) {
- continue;
- }
-
- if ((stok = strtok(NULL, (const char *)" ")) == NULL) {
- continue;
- }
- nlines = atoi(stok);
- if (nlines < 0) {
- nlines = 0;
- break;
- }
-
- if ((stok = strtok(NULL, (const char *)" ")) == NULL) {
- continue;
- }
- if (strncmp(stok, "lines", 5)) {
- continue;
- }
-
- break;
- }
-
- xfree(buf);
- return nlines;
-}
-
-/// Creates the actual cscope command query from what the user entered.
-static char *cs_create_cmd(char *csoption, char *pattern)
-{
- char *cmd;
- short search;
- char *pat;
-
- switch (csoption[0]) {
- case '0':
- case 's':
- search = 0;
- break;
- case '1':
- case 'g':
- search = 1;
- break;
- case '2':
- case 'd':
- search = 2;
- break;
- case '3':
- case 'c':
- search = 3;
- break;
- case '4':
- case 't':
- search = 4;
- break;
- case '6':
- case 'e':
- search = 6;
- break;
- case '7':
- case 'f':
- search = 7;
- break;
- case '8':
- case 'i':
- search = 8;
- break;
- case '9':
- case 'a':
- search = 9;
- break;
- default:
- (void)emsg(_("E561: unknown cscope search type"));
- cs_usage_msg(Find);
- return NULL;
- }
-
- // Skip white space before the pattern, except for text and pattern search,
- // they may want to use the leading white space.
- pat = pattern;
- if (search != 4 && search != 6) {
- while (ascii_iswhite(*pat)) {
- pat++;
- }
- }
-
- cmd = xmalloc(strlen(pat) + 2);
-
- (void)sprintf(cmd, "%d%s", search, pat);
-
- return cmd;
-}
-
-/// This piece of code was taken/adapted from nvi. do we need to add
-/// the BSD license notice?
-static int cs_create_connection(size_t i)
-{
-#ifdef UNIX
- int to_cs[2], from_cs[2];
-#endif
- char *prog, *cmd, *ppath = NULL;
-
-#if defined(UNIX)
- // Cscope reads from to_cs[0] and writes to from_cs[1]; vi reads from
- // from_cs[0] and writes to to_cs[1].
- to_cs[0] = to_cs[1] = from_cs[0] = from_cs[1] = -1;
- if (pipe(to_cs) < 0 || pipe(from_cs) < 0) {
- (void)emsg(_("E566: Could not create cscope pipes"));
-err_closing:
- if (to_cs[0] != -1) {
- (void)close(to_cs[0]);
- }
- if (to_cs[1] != -1) {
- (void)close(to_cs[1]);
- }
- if (from_cs[0] != -1) {
- (void)close(from_cs[0]);
- }
- if (from_cs[1] != -1) {
- (void)close(from_cs[1]);
- }
- return CSCOPE_FAILURE;
- }
-
- switch (csinfo[i].pid = fork()) {
- case -1:
- (void)emsg(_("E622: Could not fork for cscope"));
- goto err_closing;
- case 0: // child: run cscope.
- if (dup2(to_cs[0], STDIN_FILENO) == -1) {
- PERROR("cs_create_connection 1");
- }
- if (dup2(from_cs[1], STDOUT_FILENO) == -1) {
- PERROR("cs_create_connection 2");
- }
- if (dup2(from_cs[1], STDERR_FILENO) == -1) {
- PERROR("cs_create_connection 3");
- }
-
- // close unused
- (void)close(to_cs[1]);
- (void)close(from_cs[0]);
-#else
- // Create pipes to communicate with cscope
- int fd;
- SECURITY_ATTRIBUTES sa;
- PROCESS_INFORMATION pi;
- BOOL pipe_stdin = FALSE, pipe_stdout = FALSE; // NOLINT(readability/bool)
- STARTUPINFO si;
- HANDLE stdin_rd, stdout_rd;
- HANDLE stdout_wr, stdin_wr;
- BOOL created;
-
- sa.nLength = sizeof(SECURITY_ATTRIBUTES);
- sa.bInheritHandle = TRUE;
- sa.lpSecurityDescriptor = NULL;
-
- if (!(pipe_stdin = CreatePipe(&stdin_rd, &stdin_wr, &sa, 0))
- || !(pipe_stdout = CreatePipe(&stdout_rd, &stdout_wr, &sa, 0))) {
- (void)emsg(_("E566: Could not create cscope pipes"));
-err_closing:
- if (pipe_stdin) {
- CloseHandle(stdin_rd);
- CloseHandle(stdin_wr);
- }
- if (pipe_stdout) {
- CloseHandle(stdout_rd);
- CloseHandle(stdout_wr);
- }
- return CSCOPE_FAILURE;
- }
-#endif
- // expand the cscope exec for env var's
- prog = xmalloc(MAXPATHL + 1);
- expand_env(p_csprg, prog, MAXPATHL);
-
- // alloc space to hold the cscope command
- size_t len = strlen(prog) + strlen(csinfo[i].fname) + 32;
- if (csinfo[i].ppath) {
- // expand the prepend path for env var's
- ppath = xmalloc(MAXPATHL + 1);
- expand_env(csinfo[i].ppath, ppath, MAXPATHL);
-
- len += strlen(ppath);
- }
-
- if (csinfo[i].flags) {
- len += strlen(csinfo[i].flags);
- }
-
- cmd = xmalloc(len);
-
- // run the cscope command; is there execl for non-unix systems?
-#if defined(UNIX)
- (void)snprintf(cmd, len, "exec %s -dl -f %s", prog, csinfo[i].fname);
-#else
- // MS-Windows
- (void)snprintf(cmd, len, "%s -dl -f %s", prog, csinfo[i].fname);
-#endif
- if (csinfo[i].ppath != NULL) {
- (void)strcat(cmd, " -P");
- (void)strcat(cmd, csinfo[i].ppath);
- }
- if (csinfo[i].flags != NULL) {
- (void)strcat(cmd, " ");
- (void)strcat(cmd, csinfo[i].flags);
- }
-#ifdef UNIX
- // on Win32