Fwd: Bug: cscope interface should use absolute paths

98 views
Skip to first unread message

A. S. Budden

unread,
May 31, 2013, 9:31:27 AM5/31/13
to vim...@vim.org
Forwarding to vim-dev as requested... any cscope/vim experts here?

Al

---------- Forwarded message ----------
From: Bram Moolenaar
Date: 22 May 2013 22:02
Subject: Re: Bug: cscope interface should use absolute paths
To: A. S. Budden

Al -

> When using cscope, the path as provided to the "cs add" command is
> used. If the working directory changes, this is potentially no longer
> valid. This causes me a problem as I have a plugin that tries to
> pause cscope and restart it (so it can regenerate cscope.out without
> access conflicts). It does this by parsing "cs show" to get the file
> name(s) and then doing "cs kill" to pause and "cs add" to restart. If
> the working directory has changed, "cs add" fails.
>
> I think the fix is relatively simple: make "cs add filename" do the
> equivalent of "exe 'cs add' fnamemodify('filename', ':p')", but I
> don't know how to do that in Vim's code.
>
> An example of the issue can easily be produced with the following
> example (on Windows):
>
> * Create c:\proj1\test1.c with a simple function (I used void test1(void) { })
> * Create c:\proj2\test2.c with another simple function (I used void
> test2(void) { })
> * In each directory (c:\proj1 and c:\proj2), run "cscope -b" to create
> cscope.out
>
> First attempt (doesn't work):
>
> gvim -u NONE -U NONE
> :cd c:\proj1
> :e test1.c
> :cs add cscope.out
> :vnew
> :lcd c:\proj2
> :e test2.c
> :cs add cscope.out
> :cs show
> # Only shows one entry: cscope.out
>
> Second attempt (works):
>
> gvim -u NONE -U NONE
> :cd c:\proj1
> :e test1.c
> :cs add c:\proj1\cscope.out
> :vnew
> :lcd c:\proj2
> :e test2.c
> :cs add c:\proj2\cscope.out
> :cs show
> # Shows two entries, one for each project
>
> bugreport.txt attached as per the instructions in the documentation.

I think this was discussed before. Can you please send this to the
vim_dev list? I haven't done much on cscope myself. Hopefully someone
else knows.

- Bram

Gary Johnson

unread,
May 31, 2013, 2:42:01 PM5/31/13
to vim...@googlegroups.com
On 2013-05-31, A. S. Budden wrote:
> Forwarding to vim-dev as requested... any cscope/vim experts here?

Not an expert but a daily user.

> > When using cscope, the path as provided to the "cs add" command is
> > used. If the working directory changes, this is potentially no longer
> > valid. This causes me a problem as I have a plugin that tries to
> > pause cscope and restart it (so it can regenerate cscope.out without
> > access conflicts). It does this by parsing "cs show" to get the file
> > name(s) and then doing "cs kill" to pause and "cs add" to restart. If
> > the working directory has changed, "cs add" fails.

That's a problem with the way your plugin manages the name(s) of the
cscope database file(s).

> > I think the fix is relatively simple: make "cs add filename" do the
> > equivalent of "exe 'cs add' fnamemodify('filename', ':p')", but I
> > don't know how to do that in Vim's code.
> >
> > An example of the issue can easily be produced with the following
> > example (on Windows):
> >
> > * Create c:\proj1\test1.c with a simple function (I used void test1(void) { })
> > * Create c:\proj2\test2.c with another simple function (I used void
> > test2(void) { })
> > * In each directory (c:\proj1 and c:\proj2), run "cscope -b" to create
> > cscope.out
> >
> > First attempt (doesn't work):
> >
> > gvim -u NONE -U NONE
> > :cd c:\proj1
> > :e test1.c
> > :cs add cscope.out
> > :vnew
> > :lcd c:\proj2
> > :e test2.c
> > :cs add cscope.out
> > :cs show
> > # Only shows one entry: cscope.out

When I do this using vim on Linux (I'm not using X at the moment and
I don't have cscope for Windows), I see two entries:

# pid database name prepend path
0 28267 cscope.out <none>
1 28274 cscope.out <none>

If you're seeing only one entry, it may be a bug in the Windows
version.

However, if I then execute ":cs reset", ":cs show" shows only one
entry:

# pid database name prepend path
0 28563 cscope.out <none>

It seems to me that Vim ought to resolve and display the cscope
database files used for cscope connections in the same way it does
for files being edited. That is, a cscope.out file in the current
directory would be displayed as "cscope.out" and one in a different
directory would be displayed as "/path/to/dir/cscope.out". That
display could change as the current directory changes.

A ":cs reset" would then use a valid path to the database file of
each connection being reset, rather than just using the file name
that each connection was started with.

A ":cs show" would also then provide more useful information about
the file used for each database and might be used as described in
the first paragraph of the bug report. However, the full path name
to a database file may not fit in the space allowed in the ":cs
show" output. Long names should be shorted as is done for the
":file" command. Trying to determine the file name by scraping the
output of ":cs show" would be like trying to determine the name of
the current file by scraping the output of ":file" and would
generally not be successful.

While Vim could provide a list variable or a function for accessing
the list of cscope connection files, I think it would be acceptable
to require a plugin to manage this list itself.

Regards,
Gary

Christian Brabandt

unread,
May 31, 2013, 4:27:14 PM5/31/13
to vim...@vim.org
So you would like to have cscope always store a full path?

I think this patch does it:

iff --git a/src/if_cscope.c b/src/if_cscope.c
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -539,12 +539,17 @@
char *fname2 = NULL;
char *ppath = NULL;
int i;
+ int len;
+ int usedlen = 0;
+ char_u *fbuf = NULL;

/* get the filename (arg1), expand it, and try to stat it */
if ((fname = (char *)alloc(MAXPATHL + 1)) == NULL)
goto add_err;

expand_env((char_u *)arg1, (char_u *)fname, MAXPATHL);
+ len = (int)STRLEN(fname);
+ (void)modify_fname((char_u *)":p", &usedlen, (char_u **) &fname, &fbuf, &len);
ret = stat(fname, &statbuf);
if (ret < 0)
{


regards,
Christian
--

abu...@gmail.com

unread,
Jun 3, 2013, 12:04:26 PM6/3/13
to vim...@googlegroups.com, gary...@spocom.com
On Friday, May 31, 2013 7:42:01 PM UTC+1, Gary Johnson wrote:
> On 2013-05-31, A. S. Budden wrote:
> > Forwarding to vim-dev as requested... any cscope/vim experts here?
>
> Not an expert but a daily user.
>
> > > When using cscope, the path as provided to the "cs add" command is
> > > used. If the working directory changes, this is potentially no longer
> > > valid. This causes me a problem as I have a plugin that tries to
> > > pause cscope and restart it (so it can regenerate cscope.out without
> > > access conflicts). It does this by parsing "cs show" to get the file
> > > name(s) and then doing "cs kill" to pause and "cs add" to restart. If
> > > the working directory has changed, "cs add" fails.
>
> That's a problem with the way your plugin manages the name(s) of the
> cscope database file(s).

That's probably true. In most instances, my plugin works absolutely fine as it's expected to take over managing cscope connections entirely (i.e. it handles running cs add and cs kill based on its own internal list). However, it also tries to leave the state as it was if the user has MANUALLY added cscope connections and I quickly realised that this didn't work in certain situations because doing something like this fails:

cd c:/path/to/firstlocation
cs add cscope.out
cd c:/path/to/somewhereelse
" Now the plugin wants to pause stuff
cs kill -1
" This fails as it had no way of getting the original path to cscope.out
cs add cscope.out

Quite possible: I only tested this on Windows. Unfortunately, since there's no function-type interface to cscope, there's no way of getting the database path from the above.

> However, if I then execute ":cs reset", ":cs show" shows only one
> entry:
>
> # pid database name prepend path
> 0 28563 cscope.out <none>

That certainly looks wrong.

> It seems to me that Vim ought to resolve and display the cscope
> database files used for cscope connections in the same way it does
> for files being edited. That is, a cscope.out file in the current
> directory would be displayed as "cscope.out" and one in a different
> directory would be displayed as "/path/to/dir/cscope.out". That
> display could change as the current directory changes.

Yes.

> A ":cs reset" would then use a valid path to the database file of
> each connection being reset, rather than just using the file name
> that each connection was started with.
>
> A ":cs show" would also then provide more useful information about
> the file used for each database and might be used as described in
> the first paragraph of the bug report. However, the full path name
> to a database file may not fit in the space allowed in the ":cs
> show" output. Long names should be shorted as is done for the
> ":file" command. Trying to determine the file name by scraping the
> output of ":cs show" would be like trying to determine the name of
> the current file by scraping the output of ":file" and would
> generally not be successful.

Yes, a function interface to allow the details to be retrieved would be really nice.

> While Vim could provide a list variable or a function for accessing
> the list of cscope connection files, I think it would be acceptable
> to require a plugin to manage this list itself.

Yes, I do this already (as I said above), unfortunately this doesn't help with manually started cscope connections.

Al

abu...@gmail.com

unread,
Jun 3, 2013, 12:07:49 PM6/3/13
to vim...@googlegroups.com, vim...@vim.org

Yes!

> I think this patch does it:
>
> iff --git a/src/if_cscope.c b/src/if_cscope.c
> --- a/src/if_cscope.c
> +++ b/src/if_cscope.c
> @@ -539,12 +539,17 @@
> char *fname2 = NULL;
> char *ppath = NULL;
> int i;
> + int len;
> + int usedlen = 0;
> + char_u *fbuf = NULL;
>
> /* get the filename (arg1), expand it, and try to stat it */
> if ((fname = (char *)alloc(MAXPATHL + 1)) == NULL)
> goto add_err;
>
> expand_env((char_u *)arg1, (char_u *)fname, MAXPATHL);
> + len = (int)STRLEN(fname);
> + (void)modify_fname((char_u *)":p", &usedlen, (char_u **) &fname, &fbuf, &len);
> ret = stat(fname, &statbuf);
> if (ret < 0)
> {
>
>
> regards,
> Christian


Certainly looks promising: what do you think are the chances of getting this into Vim 7.4? As discussed in my other email in this thread, there are sadly other problems for my plugin with this (the fact that cs show won't be able to display long file-names), but this would certainly be a massive improvement on where we are now. Ideally, it would be good to have a function() interface to "cs show" to get the details programmatically, but I'd guess that's quite a lot more work for relatively little benefit.

Thanks for the patch.

Al

Christian Brabandt

unread,
Jun 3, 2013, 12:25:17 PM6/3/13
to vim...@googlegroups.com
On Mon, June 3, 2013 18:07, abu...@gmail.com wrote:
> Certainly looks promising: what do you think are the chances of getting
> this into Vim 7.4?

Looks pretty good I would say. From the latest todo list in the
repository:

Patch to store absolute path for cscope. (Christian Brabandt, 2013 May 31)

---- Fixes to be included before 7.4 above, less important stuff below ----

Several syntax file match "^\s*" which may get underlined if that's in the

> Ideally, it would be good to
> have a function() interface to "cs show" to get the details
> programmatically, but I'd guess that's quite a lot more work for
> relatively little benefit.

Probably to all :cs commands? Yes that would be nice. However I won't
be able to write a patch for that soon, as I have already too much to
do.

regards,
Christian

A. S. Budden

unread,
Jun 4, 2013, 3:26:46 AM6/4/13
to vim...@googlegroups.com
On 3 June 2013 17:25, Christian Brabandt <cbl...@256bit.org> wrote:
> On Mon, June 3, 2013 18:07, abu...@gmail.com wrote:
>> Certainly looks promising: what do you think are the chances of getting
>> this into Vim 7.4?
>
> Looks pretty good I would say. From the latest todo list in the
> repository:
>
> Patch to store absolute path for cscope. (Christian Brabandt, 2013 May 31)

Brilliant! Thank you Christian (and Bram).

>> Ideally, it would be good to
>> have a function() interface to "cs show" to get the details
>> programmatically, but I'd guess that's quite a lot more work for
>> relatively little benefit.
>
> Probably to all :cs commands? Yes that would be nice. However I won't
> be able to write a patch for that soon, as I have already too much to
> do.

That would certainly make sense, but I can see that it's not too big a priority.

Thanks again,

Al

Tony Mechelynck

unread,
Jun 4, 2013, 6:14:02 PM6/4/13
to vim...@googlegroups.com
On 31/05/13 15:31, A. S. Budden wrote:
> Forwarding to vim-dev as requested... any cscope/vim experts here?
>
> Al
>
> ---------- Forwarded message ----------
> From: Bram Moolenaar
> Date: 22 May 2013 22:02
> Subject: Re: Bug: cscope interface should use absolute paths
> To: A. S. Budden
>
> Al -
>
>> When using cscope, the path as provided to the "cs add" command is
>> used. If the working directory changes, this is potentially no longer
>> valid. This causes me a problem as I have a plugin that tries to
>> pause cscope and restart it (so it can regenerate cscope.out without
>> access conflicts). It does this by parsing "cs show" to get the file
>> name(s) and then doing "cs kill" to pause and "cs add" to restart. If
>> the working directory has changed, "cs add" fails.

IIUC, the solution to this is to provide as an optional argument to the
":cs add" command the path from which cscope.out was generated, e.g. as
follows:

" remember where I keep my sources:
" this means the parent of src/ runtime/ etc.
if 1
let $VIMSRC = '/root/.build/vim/vim-hg/vim'
endif

if has('cscope')
set cst

if has('quickfix')
set csqf=s-,c-,d-,i-,t-,e-
endif

if version < 700
cnoreabbrev csa cs add
cnoreabbrev csf cs find
cnoreabbrev csk cs kill
cnoreabbrev css cs show
cnoreabbrev csh cs help
else
cnoreabbrev <expr> csa ((getcmdtype() == ':' && getcmdpos() <= 4)? 'cs
add' : 'csa')
cnoreabbrev <expr> csf ((getcmdtype() == ':' && getcmdpos() <= 4)? 'cs
find' : 'csf')
cnoreabbrev <expr> csk ((getcmdtype() == ':' && getcmdpos() <= 4)? 'cs
kill' : 'csk')
cnoreabbrev <expr> css ((getcmdtype() == ':' && getcmdpos() <= 4)? 'cs
show' : 'css')
cnoreabbrev <expr> csh ((getcmdtype() == ':' && getcmdpos() <= 4)? 'cs
help' : 'csh')
endif

command -bar Cscope cs add $VIMSRC/src/cscope.out $VIMSRC/src

set csverb
endif


The ":if 1" is to avoid an error in a minimal-features Vim compiled with
no expression evaluation.


Best regards,
Tony.
--
THEOREM: VI is perfect.
PROOF: VI in roman numerals is 6. The natural numbers < 6 which divide
6 are
1, 2, and 3. 1+2+3 = 6. So 6 is a perfect number. Therefore, VI is
perfect.
QED
-- Arthur Tateishi

Christian Brabandt

unread,
Jun 5, 2013, 1:36:56 AM6/5/13
to vim...@googlegroups.com
On Wed, June 5, 2013 00:14, Tony Mechelynck wrote:
> On 31/05/13 15:31, A. S. Budden wrote:
>>> When using cscope, the path as provided to the "cs add" command is
>>> used. If the working directory changes, this is potentially no longer
>>> valid. This causes me a problem as I have a plugin that tries to
>>> pause cscope and restart it (so it can regenerate cscope.out without
>>> access conflicts). It does this by parsing "cs show" to get the file
>>> name(s) and then doing "cs kill" to pause and "cs add" to restart. If
>>> the working directory has changed, "cs add" fails.
>
> IIUC, the solution to this is to provide as an optional argument to the
> ":cs add" command the path from which cscope.out was generated, e.g. as
> follows:

No, this is a different problem, as explained by Gary here:
http://article.gmane.org/gmane.editors.vim.devel/39984

regards,
Christian

Reply all
Reply to author
Forward
0 new messages