Robert Bragg <[email protected]> wrote:
> Hi,
>
> So it turns out, I'm the only one in the world that wants more than 8
> cscope connections, but I really do :-)
Please find attached a patch (against Vim-7.2.160) that performs
dynamic allocation of cscope connections. It gets rid of the
hard-coded limitation of 8 connections max (no limit anymore).
Remark: while writing the patch, I found and fixed a bug in
if_cscope.c:1595:
1595 if ((i >= CSCOPE_MAX_CONNECTIONS || i < -1 || csinfo[i].fname == NULL)
1596 && i != -1)
This was incorrect: 'i' can be -1 (when doing ":cs kill -1") and it
then accessed csinfo[-1].fname (illegal memory access). Valgrind
could not detect it because csinfo was in .bss section before patch
and Valgrind does not know about boundaries of buffers in .bss.
But Valgrind could detect the bug when csinfo is dynamically
allocated.
Regards
-- Dominique
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---
Index: src/if_cscope.h
===================================================================
RCS file: /cvsroot/vim/vim7/src/if_cscope.h,v
retrieving revision 1.6
diff -c -r1.6 if_cscope.h
*** src/if_cscope.h 25 Aug 2008 02:35:55 -0000 1.6
--- src/if_cscope.h 26 Apr 2009 21:22:21 -0000
***************
*** 25,31 ****
#define CSCOPE_SUCCESS 0
#define CSCOPE_FAILURE -1
- #define CSCOPE_MAX_CONNECTIONS 8 /* you actually need more? */
#define CSCOPE_DBFILE "cscope.out"
#define CSCOPE_PROMPT ">> "
--- 25,30 ----
Index: src/if_cscope.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/if_cscope.c,v
retrieving revision 1.36
diff -c -r1.36 if_cscope.c
*** src/if_cscope.c 22 Apr 2009 14:25:01 -0000 1.36
--- src/if_cscope.c 26 Apr 2009 21:22:22 -0000
***************
*** 46,52 ****
static int cs_find __ARGS((exarg_T *eap));
static int cs_find_common __ARGS((char *opt, char *pat, int, int, int));
static int cs_help __ARGS((exarg_T *eap));
- static void cs_init __ARGS((void));
static void clear_csinfo __ARGS((int i));
static int cs_insert_filelist __ARGS((char *, char *, char *,
struct stat *));
--- 46,51 ----
***************
*** 66,72 ****
static int cs_show __ARGS((exarg_T *eap));
! static csinfo_T csinfo[CSCOPE_MAX_CONNECTIONS];
static int eap_arg_len; /* length of eap->arg, set in
cs_lookup_cmd() */
static cscmd_T cs_cmds[] =
--- 65,74 ----
static int cs_show __ARGS((exarg_T *eap));
! static csinfo_T * csinfo = NULL;
! static int 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[] =
***************
*** 145,167 ****
}
case EXP_CSCOPE_KILL:
{
! static char_u connection[2];
/* ":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. */
! for (i = 0, current_idx = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
if (csinfo[i].fname == NULL)
continue;
if (current_idx++ == idx)
{
! /* Connection number fits in one character since
! * CSCOPE_MAX_CONNECTIONS is < 10 */
! connection[0] = i + '0';
! connection[1] = NUL;
! return connection;
}
}
return (current_idx == idx && idx > 0) ? (char_u *)"-1" : NULL;
--- 147,166 ----
}
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. */
! 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), "%d", i);
! return (char_u *)connection;
}
}
return (current_idx == idx && idx > 0) ? (char_u *)"-1" : NULL;
***************
*** 224,230 ****
{
cscmd_T *cmdp;
- cs_init();
if ((cmdp = cs_lookup_cmd(eap)) == NULL)
{
cs_help(eap);
--- 223,228 ----
***************
*** 285,292 ****
{
int ret = FALSE;
- cs_init();
-
if (*eap->arg == NUL)
{
(void)EMSG(_("E562: Usage: cstag <ident>"));
--- 283,288 ----
***************
*** 442,448 ****
if (num < 0 || num > 4 || (num > 0 && !dbpath))
return FALSE;
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
if (!csinfo[i].fname)
continue;
--- 438,444 ----
if (num < 0 || num > 4 || (num > 0 && !dbpath))
return FALSE;
! for (i = 0; i < csinfo_size; i++)
{
if (!csinfo[i].fname)
continue;
***************
*** 686,692 ****
short i;
short cnt = 0;
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
if (csinfo[i].fname != NULL)
cnt++;
--- 682,688 ----
short i;
short cnt = 0;
! for (i = 0; i < csinfo_size; i++)
{
if (csinfo[i].fname != NULL)
cnt++;
***************
*** 1114,1120 ****
{
int i;
char *cmd;
! int nummatches[CSCOPE_MAX_CONNECTIONS], totmatches;
#ifdef FEAT_QUICKFIX
char cmdletter;
char *qfpos;
--- 1110,1117 ----
{
int i;
char *cmd;
! int *nummatches;
! int totmatches;
#ifdef FEAT_QUICKFIX
char cmdletter;
char *qfpos;
***************
*** 1125,1137 ****
if (cmd == NULL)
return FALSE;
/* send query to all open connections, then count the total number
* of matches so we can alloc matchesp all in one swell foop
*/
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
nummatches[i] = 0;
totmatches = 0;
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL)
continue;
--- 1122,1138 ----
if (cmd == NULL)
return FALSE;
+ nummatches = (int *)alloc(sizeof(int)*csinfo_size);
+ if (nummatches == NULL)
+ return FALSE;
+
/* send query to all open connections, then count the total number
* of matches so we can alloc matchesp all in one swell foop
*/
! for (i = 0; i < csinfo_size; i++)
nummatches[i] = 0;
totmatches = 0;
! for (i = 0; i < csinfo_size; i++)
{
if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL)
continue;
***************
*** 1156,1162 ****
--- 1157,1166 ----
char *buf;
if (!verbose)
+ {
+ vim_free(nummatches);
return FALSE;
+ }
buf = (char *)alloc((unsigned)(strlen(opt) + strlen(pat) + strlen(nf)));
if (buf == NULL)
***************
*** 1167,1172 ****
--- 1171,1177 ----
(void)EMSG(buf);
vim_free(buf);
}
+ vim_free(nummatches);
return FALSE;
}
***************
*** 1219,1224 ****
--- 1224,1230 ----
(void)EMSG(buf);
vim_free(buf);
}
+ vim_free(nummatches);
return FALSE;
}
}
***************
*** 1266,1271 ****
--- 1272,1278 ----
}
mch_remove(tmp);
vim_free(tmp);
+ vim_free(nummatches);
return TRUE;
}
else
***************
*** 1277,1282 ****
--- 1284,1290 ----
/* read output */
cs_fill_results((char *)pat, totmatches, nummatches, &matches,
&contexts, &matched);
+ vim_free(nummatches);
if (matches == NULL)
return FALSE;
***************
*** 1331,1356 ****
} /* cs_help */
- /*
- * PRIVATE: cs_init
- *
- * initialize cscope structure if not already
- */
- static void
- cs_init()
- {
- short i;
- static int init_already = FALSE;
-
- if (init_already)
- return;
-
- for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
- clear_csinfo(i);
-
- init_already = TRUE;
- } /* cs_init */
-
static void
clear_csinfo(i)
int i;
--- 1339,1344 ----
***************
*** 1448,1454 ****
#endif
i = -1; /* can be set to the index of an empty item in csinfo */
! for (j = 0; j < CSCOPE_MAX_CONNECTIONS; j++)
{
if (csinfo[j].fname != NULL
#if defined(UNIX)
--- 1436,1442 ----
#endif
i = -1; /* can be set to the index of an empty item in csinfo */
! for (j = 0; j < csinfo_size; j++)
{
if (csinfo[j].fname != NULL
#if defined(UNIX)
***************
*** 1475,1483 ****
if (i == -1)
{
! if (p_csverbose)
! (void)EMSG(_("E569: maximum number of cscope connections reached"));
! return -1;
}
if ((csinfo[i].fname = (char *)alloc((unsigned)strlen(fname)+1)) == NULL)
--- 1463,1487 ----
if (i == -1)
{
! i = csinfo_size;
! if (csinfo_size == 0)
! {
! /* First time allocation: allocate only 1 connection. It should
! * be enough for most users. If more is needed, csinfo will be
! * reallocated. */
! csinfo_size = 1;
! csinfo = (csinfo_T *)alloc_clear(sizeof(csinfo_T));
! }
! else
! {
! /* Reallocate space for more connections. */
! csinfo_size *= 2;
! csinfo = vim_realloc(csinfo, sizeof(csinfo_T)*csinfo_size);
! }
! if (csinfo == NULL)
! return -1;
! for (j = csinfo_size/2; j < csinfo_size; j++)
! clear_csinfo(j);
}
if ((csinfo[i].fname = (char *)alloc((unsigned)strlen(fname)+1)) == NULL)
***************
*** 1585,1599 ****
/* It must be part of a name. We will try to find a match
* within all the names in the csinfo data structure
*/
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
if (csinfo[i].fname != NULL && strstr(csinfo[i].fname, stok))
break;
}
}
! if ((i >= CSCOPE_MAX_CONNECTIONS || i < -1 || csinfo[i].fname == NULL)
! && i != -1)
{
if (p_csverbose)
(void)EMSG2(_("E261: cscope connection %s not found"), stok);
--- 1589,1602 ----
/* It must be part of a name. We will try to find a match
* within all the names in the csinfo data structure
*/
! for (i = 0; i < csinfo_size; i++)
{
if (csinfo[i].fname != NULL && strstr(csinfo[i].fname, stok))
break;
}
}
! if ((i != -1) && (i >= csinfo_size || i < -1 || csinfo[i].fname == NULL))
{
if (p_csverbose)
(void)EMSG2(_("E261: cscope connection %s not found"), stok);
***************
*** 1602,1608 ****
{
if (i == -1)
{
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
if (csinfo[i].fname)
cs_kill_execute(i, csinfo[i].fname);
--- 1605,1611 ----
{
if (i == -1)
{
! for (i = 0; i < csinfo_size; i++)
{
if (csinfo[i].fname)
cs_kill_execute(i, csinfo[i].fname);
***************
*** 1862,1868 ****
if (buf == NULL)
return;
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
if (nummatches_a[i] < 1)
continue;
--- 1865,1871 ----
if (buf == NULL)
return;
! for (i = 0; i < csinfo_size; i++)
{
if (nummatches_a[i] < 1)
continue;
***************
*** 1934,1940 ****
if ((cntxts = (char **)alloc(sizeof(char *) * totmatches)) == NULL)
goto parse_out;
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
if (nummatches_a[i] < 1)
continue;
--- 1937,1943 ----
if ((cntxts = (char **)alloc(sizeof(char *) * totmatches)) == NULL)
goto parse_out;
! for (i = 0; i < csinfo_size; i++)
{
if (nummatches_a[i] < 1)
continue;
***************
*** 2390,2399 ****
int i;
char buf[20]; /* for sprintf " (#%d)" */
/* malloc our db and ppath list */
! dblist = (char **)alloc(CSCOPE_MAX_CONNECTIONS * sizeof(char *));
! pplist = (char **)alloc(CSCOPE_MAX_CONNECTIONS * sizeof(char *));
! fllist = (char **)alloc(CSCOPE_MAX_CONNECTIONS * sizeof(char *));
if (dblist == NULL || pplist == NULL || fllist == NULL)
{
vim_free(dblist);
--- 2393,2405 ----
int i;
char buf[20]; /* for sprintf " (#%d)" */
+ if (csinfo_size == 0)
+ return CSCOPE_SUCCESS;
+
/* malloc our db and ppath list */
! dblist = (char **)alloc(csinfo_size * sizeof(char *));
! pplist = (char **)alloc(csinfo_size * sizeof(char *));
! fllist = (char **)alloc(csinfo_size * sizeof(char *));
if (dblist == NULL || pplist == NULL || fllist == NULL)
{
vim_free(dblist);
***************
*** 2402,2408 ****
return CSCOPE_FAILURE;
}
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
dblist[i] = csinfo[i].fname;
pplist[i] = csinfo[i].ppath;
--- 2408,2414 ----
return CSCOPE_FAILURE;
}
! for (i = 0; i < csinfo_size; i++)
{
dblist[i] = csinfo[i].fname;
pplist[i] = csinfo[i].ppath;
***************
*** 2412,2418 ****
}
/* rebuild the cscope connection list */
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
if (dblist[i] != NULL)
{
--- 2418,2424 ----
}
/* rebuild the cscope connection list */
! for (i = 0; i < csinfo_size; i++)
{
if (dblist[i] != NULL)
{
***************
*** 2510,2516 ****
MSG_PUTS_ATTR(
_(" # pid database name prepend path\n"),
hl_attr(HLF_T));
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
{
if (csinfo[i].fname == NULL)
continue;
--- 2516,2522 ----
MSG_PUTS_ATTR(
_(" # pid database name prepend path\n"),
hl_attr(HLF_T));
! for (i = 0; i < csinfo_size; i++)
{
if (csinfo[i].fname == NULL)
continue;
***************
*** 2539,2546 ****
{
int i;
! for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++)
cs_release_csp(i, TRUE);
}
#endif /* FEAT_CSCOPE */
--- 2545,2554 ----
{
int i;
! for (i = 0; i < csinfo_size; i++)
cs_release_csp(i, TRUE);
+ vim_free(csinfo);
+ csinfo_size = 0;
}
#endif /* FEAT_CSCOPE */
*** ../vim-runtime/doc/if_cscop.txt 2009-03-22 20:39:56.000000000 +0100
--- doc/if_cscop.txt 2009-04-26 23:11:05.000000000 +0200
***************
*** 355,367 ****
The DJGPP-built version from http://cscope.sourceforge.net is known to not
work with Vim.
! There are a couple of hard-coded limitations:
!
! 1. The maximum number of cscope connections allowed is 8. Do you
! really need more?
!
! 2. Doing a |:tjump| when |:cstag| searches the tag files is not
! configurable (e.g., you can't do a tselect instead).
==============================================================================
6. Suggested usage *cscope-suggestions*
--- 355,362 ----
The DJGPP-built version from http://cscope.sourceforge.net is known to not
work with Vim.
! Hard-coded limitation: doing a |:tjump| when |:cstag| searches the tag files
! is not configurable (e.g., you can't do a tselect instead).
==============================================================================
6. Suggested usage *cscope-suggestions*