Many times when I am watching others code I just want to find where and how a variable is defined. Normally what I do now is look for the type of the variable until I find the definition, that is very time consuming. And I guess that there are some tools that can help me in this rutinary situation. Any suggestion in some tools or commands to help me in this task?.
I know that using a GUI and creating a project this is done automatically I am talking of a way to do this without a GUI. I am working with only text mode. I am running under Linux and I am using C/C++, but suggestions for other languages are welcome.
Thanks a lot.
A possible solution
Michel in one of his comments propose a simple an effective solution define again the variable, in that case in compilation time, the compiler will inform where is the previous definiton. Of course to apply this solution we need to think previously in the locality of the variable.
You've already given the most appropriate tool: an IDE. This is exactly the kind of thing which an IDE excels at. Why would you not want to use an IDE if you're finding development painful without one?
Note that Emacs, Vim etc can work as IDEs - I'm not talking about forcing you the world of GUIs if you want to stay in a text-only situation, e.g. because you're SSHing in.
(I'm really not trying to be rude here. I just think you've discounted the obvious solution without explaining why.)
Edit: OK, you say you're using C++. I'm editing my response. I would use the C preprocessor and then grep for the variable. It will appear in the first place.
cpp -I...(preprocessor options here) file.cpp | grep variable
The C preprocessor will join all the includes that the program uses, and the definition has to be before any usage of that variable in the file. Not a perfect thing, but without an IDE or a complete language description/managing tool, you only have the text.
Another option would be using ctags. It understands the C and C++ syntaxes (among others), and can be searched for variables and functions using command line tools, emacs and vi, among others.
I use cscope and ctags-exuberant religiously. Run it once on my code base and then in Vim, I can use various commands like ^] or [D or [I or similar to find any definitions or declarations for a given word.
This is similar to facilities provided by mega-IDEs like Visual Studio and Eclipse.
Cscope also functions as a stand-alone tool that performs these searches.
I use one of three methods:
I will use CTags to process my source tree (nightly) and then can easily use commands in Vim (or other editors) to jump right to the definition.
I will just use grep (linux) or findstr (windows) to look for all occurrences of the variable name or type. The definition is usually quite obvious.
In Vim, you can just search backward in the scope and often find what you are looking for.
Grep for common patterns for variable declarations. Example: *, &, > or an alphanumeric followed by one or more whitespace characters then the name of the variable. Or variable name followed by zero or more whitespace characters, then a left parenthesis or a semicolon. Unless it was defined under really weird circumstances (like with some kind of macro), it works every time.
In VIM you can use gd to see local variable declarations or gD to see global variable declarations, if they're defined in the current file. Reference Go_to_definition_using_g
You can also use [i to see the definition without jumping to it, or [I to see all occurrences of the variable in all the included files as well, which will naturally show the definition as well.
If you work in Microsoft Visual Studio (which I think you could use for C++ as well, but would require working on a Windows workstation) there's an easily accessible right-click menu option for "Go to Definition...", which will take you to the definition of any currently marked variable, type or method.
if you insist on staying text mode, you can do this with either emacs or vi with the appropriate plug-ins.
But really, move into the 21st century.
EDIT: You commented that you are doing this over SSH because you need the build speed of the remote server cluster.
In that case, mount the drive on your local machine and use an IDE, and just SSH in to kick off a build.
Related
Sometimes I am reading some code and would like to find the definition for a certain symbol, but it is sprinkled throughout the code to such an extent that grep is more or less insufficient for pointing me to its definition.
For example, I am working with Zlib and I want to figure out what FAR means.
Steven#Steven-PC /c/Users/Steven/Desktop/zlib-1.2.5
$ grep "FAR" * -R | wc -l
260
That's a lot to scan through. It turns out it is in fact #defined to nothing but it took me some time to figure it out.
If I was using Eclipse I would have it easy because I can just hover over the symbol and it will tell me what it is.
What kinds of tools out there can I use to analyze code in this way? Can GCC do this for me? clang maybe? I'm looking for something command-line preferably. Some kind of tool that isn't a full fledged IDE at any rate.
You may want to check out cscope, it's basically made for this, and a command line tool (if you like, using ncurses). Also, libclang (part of clang/llvm) can do so - but that's just a library (but took me just ~100 lines of python to use libclang to emulate basic cscope features).
cscope requires you to build a database first. libclang can parse code "live".
If the variable is not declared in your curernt file, it is declared in an included file, i.e. a .h. So you can limit the amount of data by performing a grep only on those files.
Moreover, you can filter whole word matches with -w option of grep.
Try:
grep -w "FAR" *.h -R | wc -l
Our Source Code Search Engine (SCSE) is kind of graphical grep that indexes a large code base according to the tokens of its language(s) (e.g., C, Java, COBOL, ...). Queries are stated in terms of the tokens, not strings, so finding an identifier won't find it in the middle of a comment. This minimizes false positives, and in a big code base these can be a serious waste of time. Found hits are displayed one per line; a click takes to the source text.
One can do queries from the command line and get grep-like responses, too.
A query of the form of
I=foo*
will find all uses of any identifier that starts with the letters "foo".
Queries can compose mulitiple tokens:
I=foo* '[' ... ']' '='
finds assignments to a subscripted foo ("..." means "near").
For C, Java and COBOL, the SCSE can find reads, writes, updates, and declarations of variables.
D=*baz
finds declarations of variables whose names end in "baz". I think this is what OP is looking for.
While SCSE works for C++, it presently can't find reads/writes/updates/declarations in C++. It does everything else.
The SCSE will handle mixed languages with aplomb. An "I" query will search across all langauges that have identifiers, so you can see cross language calls relatively easily, since the source and target identifiers tend to be the same for software engineering reasons.
gcc can output the pre-processing result, with all macro definitions with gcc -E -dD. The output file would be rather larger, often due to the nested system headers. But the first appearance of a symbol is usually the declaration (definition). The output use #line to show the part pre-processed result belong to source/header file, so you can find where it is originally declared.
To get the exact result when the file is compiled, you may need to add all other parameters used to compile the file, like -I, -D, etc. In fact, I always copy a result compilation command line, and add -E -dD to the beginning, and add (or change) -o in case I accidental overwrite anything.
There is gccxml, but I am not aware of tools that build on top of it. clang and LLVM are suited for such stuff, too; equally, I am not aware of standalone tools that build on them.
Apart from that: QtCreator and code::blocks can find the declartion, too.
So what is it about a "full fledged IDE" you don't want? If its a little speed, I found netbeans somewhat usefull when I was in school, but really for power and speed and general utility I would like to reccomend emacs. It has key board shortcuts for things like this. Keep in mind, its a learning curve to be sure, but once you are over the hump there is no going back.
I am making a c++ program with vi. It has only one file but it's getting kind of big. It would be nice if I could easily see all the functions I created and jump to any one of them without having to search for them. Can vi do this, or is there a similar program that can?
This seems like a dup of Jump to function definition in vim.
To sum up that answer, use ctags, and take a look at Vim and Ctags tips and tricks.
I use a vim plugin to do this :
http://www.vim.org/scripts/script.php?script_id=273
It summarizes classes, struct, function, with jump functionality.
I'm trying to understand the source code of a fairly large C++ project. The source wasn't written with an IDE, so I don't have a "goto" button to go straight to the function definition.
For example:
srand();
I want to find out exactly where the function srand() is defined.
The only method I can come up with is manually checking all the header includes to recursively find the declaration and the corresponding file for the definition.
This is a linux environment and the source is compiled with g++ (using cmake).
Look into the ctags program.
ctags generates a file with information on the locations in the code where each identifier is used. It is then possible to use a plugin for your editor of choice that will allow you to jump to the definition of any identifier. (very mature ctags plugins exist for Vim and Emacs, and probably for most other popular editors as well.)
If you are using VI you can shift+k that will open it in a man page, if there is one for this word. I believe it automatically is set to search in man(3) but i'm not 100% sure. At least this way you can know wether it's a system function or not.
Another option is to use Doxygen to setup the call graphs and let it generate the source (even if there are no comments). With the call graph you can easily spot from where each function is coming from.
So I've been working on a relatively large project by myself, and I've come to realise that some of the variable names earlier on were.. less than ideal.
But how does one change variable names in a project easily? Is there such a tool that can go through a project directory, parse all the files, and then replace the variable names to the desired one? It has to be smart enough to understand the language I imagine.
I was thinking of using regexp (sed/awk on linux?) tools to just replace the variable name, but there were many times where my particular variable is also included as a part of strings.
There's also the issue about changing stuff on a c++ namespace, because there is actually two classes in my project that share the same name, but are in different namespaces.
I remember visual studio being able to do this, but what's the safest and most elegant way to do this on linux?
It's called refactoring, but I don't remember if there's a great way to do it in C++ -- I think maybe Eclipse C++ had it; might be worth taking a look.
Safest (non automated way) way:
Make sure all your unit tests work.
Save everything into source control.
Globally replace var with XXXvarXXX (seriously)
a. Or maybe just the files you think need editing.
Try and compile. Everything that does not compile is easy to undo just remove the XXX.
When it compiles run the unit tests.
When the unit tests work. Do a global replace of XXXvarXXX to the new name.
Make sure the unit tests still work
Save everything in source control.
Tongue only half in cheek. :-)
I remember visual stuio being able to do this, but what's the safest and most elegant way to do this on linux?
You can do pretty much what you used to do in visual studio in Eclipse using the re-factoring tools, which is available for Linux.
$400 a f'n copy, but here you go: http://www.xref.sk/xrefactory/download.html
I've of course never used it.
I know C# and visual studio has a great variable changer, but does it work through all the documents im not sure. I know when you change a variable in C# it pops up in the beside the Variable text. Change All
However you may be stuck with the only option. Change variables and see where the compiler goes wrong. However its not ideal, but may be your only choice
use private variables, rename the variable and the obvious uses, correct the compiler errors.
After frequently coming across recommendation not to use leading and double underscores in C/C++ identifiers I decided to fix all our sources once and for all. What I need to do now is convert _Identifier to Identifier_.
Should I use a specialized tool for this task of regular expressions will do for this job? In latter case what is the pattern to match C/C++ identifier?
Although I am one of those that frequently points out that names with leading underscores may be reserved, I strongly recommend you don't do this unless you are experiencing problems caused by the names. Making this global change will make your version control system less useful than it might otherwise be by causing all sorts of spurious diffs. Also, there is a chance of creating duplicate names.
Also, there are many underscore prefixed names that re perfectly valid. One thinks immediately of __LINE__ and __FILE__ etc, and of all the names of non-standard functions that may be provided by
your specific implementation. Filtering out those names will be far from trivial (I would say next to impossible), certainly a simple Perl or sed script will not be enough.
So instead, I would encourage you to change the names on a file by file basis as you make other changes to the code. Change your programming standards to avoid the leading underscore names and write new code in accordance with the standards.
If you use Visual Studio, there are refactoring plugins such as Visual Assist X to help you with this.
Perl should do the job, but there's Coccinelle for when it gets tricky.
Netbeans can do this for the whole project, using the Refactor->Rename menu command. But it only works for a single identifier a time, so you'll need to reiterate for every identifier you need to change.
If your regression tests are solid, then you should have no problems if you just write a quick perl script to replace everything and run the test suite. If you don't have solid regression tests...well, then you can do the perl script replacement and just rebuild the code. If the compilation works, then chances are pretty good that everything is fine. In other words, try the quick solution, and only use a specialized tool if that doesn't work.