2

When I try to use a file name in a variable for the cs add command, I cannot understand what happens. I'm using a bash script myscript.sh which returns the path name of cscope database (/mydir/cscope.out) based on the current file name (/mydir/myfile.py):

:let db = system("myscript.sh " . expand("%:p"))

After that, when I call:

:cs add db

I get:

"E563: stat(/mydir/db) error 2"

When I call:

:exe "cs add " . db

I get:

"E563: stat(/mydir/cscope.out^@) error 2"

/mydir/cscope.out is the right file name which returned by myscript.sh, but where the ^@ thing comes from? How do I correctly use the variable with a parameter in this case?

P.S. When cs add is called with plain file name:

:cs add /mydir/cscope.out

Connection is created OK and no errors is reported.

:echo db

Displays:

/mydir/cscope.out

Press ENTER or type command to continue
muru
  • 24,838
  • 8
  • 82
  • 143
Al Berger
  • 393
  • 1
  • 11
  • 2
    ^@ is Ctrl-@, indicating the ASCII NUL character, which shouldn't be there since system replaces NULs with SOH (^A). – muru Dec 16 '15 at 12:46
  • 1
    Not sure, but maybe your script myscript.sh includes a new line character at the end of its output. ^@ is the caret notation of a null character (https://en.wikipedia.org/wiki/Null_character). You could try getting rid of it like this: let db=system("myscript.sh " . expand("%:p"))[:-2] or let db=substitute(system("myscript.sh " . expand("%:p"), '\n$', '', '') or let db=substitute(system("myscript.sh " . expand("%:p"), '[[:cntrl:]]', '', 'g'). Not tested so I don't know if any of these commands will work in your particular case. Found them here : http://superuser.com/a/935646 – saginaw Dec 16 '15 at 12:51
  • @muru Thanks. The myscript.sh indeed uses -print0 in the 'find' command. – Al Berger Dec 16 '15 at 12:54
  • @saginaw Thanks, your answer solves the issue. – Al Berger Dec 16 '15 at 12:55

1 Answers1

2

If you're using GNU find for this, then perhaps you can use the -printf option:

find /some/path -name cscope.out -printf '%p' -quit

This will just print the path of the matched file without any additional characters. -quit instructs it to exit after the first match. This should avoid the extra NUL and let you use the :exe command.

muru
  • 24,838
  • 8
  • 82
  • 143
  • I use the 'find' for listing files in the project directory tree, which are used for building db (cscope work only with *.c files by default). But 'find' works OK without -print0 as well (-print0 is needed for filenames with \n, as I understand). – Al Berger Dec 16 '15 at 13:50
  • @AlBerger -print0 is useful if you're handling multiple files in the output, but from what you have said so far, it seems to me the script only outputs one filename. – muru Dec 16 '15 at 13:53
  • Yes, the script outputs the name of the database, but it also rebuilds it when it's connected for the first time (the 'find' is used for rebuilding the database). – Al Berger Dec 16 '15 at 14:40
  • Well, if 'find' is used for rebuilding, then where the \0 comes from? =) I don't know. The file name is outputted with 'echo $dbname'. Anyways, the issue was solved by [:-2] – Al Berger Dec 16 '15 at 14:43
  • @AlBerger then we have a doubly impossible scenario: echo isn't going to print a NUL (not like that anyway), and system replaces NULs, as I previously noted. – muru Dec 16 '15 at 16:55