Help with automated renaming in C++ - c++

Here is my issue:
I have a large library of code where all of the class names begin with Agui. For example:
class AguiWidget
{
};
class AguiBitmap
{
};
also, all the hpp and cpp files are named like this also:
AguiWidget.hpp
etc.
The library also does not use a namespace.
all of the enums begin and use Agui:
ex:
enum AguiKeyEnum
{
AGUI_KEY_SPACE,
AGUI_KEY_ENTER
};
The include guards also use ex:
AGUI_WIDGET_HPP
So,
My task is to remove all the Agui, AGUI references from the entire project (all the classes and enums), then to encapsulate all the classes into namespace agui.
What would be the easiest way to do this. I also need the hpp and cpp files to no longer have Agui in the filename.
I use MSVC 2008 as an IDE if that helps.
Thanks!

You need to use a global find and replace tool. If you have Visual Studio 2008, then it is already built-in. Once you rename all the classes and namespaces, then use another tool to rename the files or build a script to do it for you.

As a Linux user (which you aren't, but you could use Cygwin or a separate machine), I'd use the program sed to strip the prefixes. I'd start with this, then review the diffs vs. source control:
sed -i 's/Agui//g; s/AGUI_//g' *.hpp *.cpp # and maybe *.sln *.proj
Then, renaming the files:
for f in *.hpp *.cpp; do mv $f ${f#Agui}; done # or source control's mv
Then all that's left is to add namespacing. You could probably get this done using sed as well, but if the number of files is not huge I'd just do it by hand. The namespace closing braces are trivial to add though:
for f in *.hpp *.cpp; do (echo '} // namespace agui' >> $f); done
The opening braces you might want to take a little more care to add, depending on your existing code's structure.
Oh, and look, sed for Windows: http://gnuwin32.sourceforge.net/packages/sed.htm (I haven't used this).

I would suggest either using
cygwin + recursive find + script - use sed for changing names, mv to change files
or figuring how to do the equivalent in powershell.
With the right regular expressions it should work fine.
Make sure to copy the entire directory structure before editing, as it may take a few iterations to debug.

Related

Automatically fix filename cases in C++ codebase?

I am porting a C++ codebase which was developed on a Windows platform to Linux/GCC. It seems that the author didn't care for the case of filenames, so he used
#include "somefile.h"
instead of
#include "SomeFile.h"
to include the file which is actually called "SomeFile.h". I was wondering if there is any tool out there to automatically fix these includes? The files are all in one directory, so it would be easy for the tool to find the correct names.
EDIT: Before doing anything note that I'm assuming you either have copies of the files off ot the side or preferably that you have a baseline version in source control should you need to roll back for any reason.
You should be able to do this with sed: Something like sed -i 's/somefile\.h/SomeFile.H/I' *.[Ch]
This means take a case-insensitive somefile (trailing /I) and do an in-place (same file) replacement (-i) with the other text, SomeFile.H.
You can even do it in a loop (totally untested):
for file in *.[Ch]
do
sed -i "s/$file/$file/I" *.[Ch]
done
I should note that although I don't believe this applies to you, Solaris sed doesn't support -i and you'd have to install GNU sed or redirect to a file and rename.
Forgive my, I'm away from my linux environment right now so I can't test this myself, but I can tell you what utilities you would need to use to do it.
Open a terminal and use cd to navigate to the correct directory.
cd ~/project
Get a list of all of the .h files you need. You should be able to accomplish this with the shell's wildcard expansion without any effort.
ls include/*.h libs/include/*.h
Get a list of all of the files in the entire project (.c, .cpp, .h, .whatever), anything that can #include "header.h". Again, wildcard expansion.
ls include/*.h libs/include/*.h *.cpp libs/*.cpp
Iterate over each file in the project with a for loop
for f in ... # wildcard file list
do
echo "Looking in $f"
done
Iterate over each header file with a for loop
for h in ... # wildcard header list
do
echo "Looking for $h"
done
For each header in each project file, use sed to search for #include "headerfilename.h", and replace with #include "HeaderFileName.h" or whatever the correct case is.
Warning: Untested and probably dangerous: This stuff is a place to start and should be thoroughly tested before use.
h_escaped=$(echo $h | sed -e 's/\([[\/.*]\|\]\)/\\&/g') # escapes characters in file name
argument="(^\s*\#include\s*\")$h_escaped(\"\s*\$)" # I think this is right
sed -i -e "s/$argument/\$1$h\$2/gip"`
Yes, I know it looks awful.
Things to consider:
Rather than going straight to running this on your production codebase, test it thoroughly first.
sed can eat files like a VCR can eat tapes.
Make a backup.
Make another backup.
This is an O(N^2) operation involving hard disk access, and if your project is large it will run slowly. If your project is not gigantic, don't bother, but if it is, consider doing something to pipe sed's output to other seds.
Your search should be case insensitive: it should match #include, #INCLUDE, #iNcLuDe, and any combination of case present in the existing header filename, as well as any amount of whitespace between the include and the header. Bonus points if you preserve whitespace.
Use Notepad++ to do a 'Find in Files' and replace.
From toolbar:
Search - Find in Files.
Then complete the 'Find what' and 'Replace with'.

emacs drill down shortcut

I am new to emacs. In Netbeans, you can right click on any object and it will send you directly to the header or implementation file. Is there a shortcut key to do this in emacs?
You have to create a TAGS file first.
If you're on linux:
$ ctags -e -R *.h *.cpp
// this will create tags for all .h and .cpp files,
// starting from the current directory, and recursing into subdirectories.
// -e : emacs tags (as oposed to vi tags, the default)
// -R : recursive
You can also add to an existing tags file by using the --append flag. For example:
$ ctags --append -e -R *.h *.cpp /home/user/jdoe/thirdparty
// This will add to the TAGS file in the current directory
When you want to jump to a symbol definition, in emacs use M-x find-tag, or M-.. It'll ask you where the TAGS file is, and you're set. To pop out, use M-x pop-tag-mark, by default mapped to M-*.
Note: ctags is alright, but since it's not a compiler, sometimes it'll take you to the wrong place.
You can use etags to provide a similar functionality. Once your TAGS file is created, you can use the M-. shortcut that invokes (find-tag).
As with everything: Emacs gives you several ways to do something, in this case a bunch of them don't work out of the box. You can either use etags or if you need a really big hammer semantic, which is part of the cedet project. This will give you much more then simply jumping into a header file, but maybe that is what you need.

How can I quickly search all included header files in a project for a specific symbol?

Here's a problem I've had recently that just HAS to be a common pain to others here.
I'm working with someone else's legacy C code and need to find where a function or macro was defined. The code #includes a bunch of different standard system libraries in addition to those from the specific project.
Is there a tool or technique to quickly find where a specific function, macro, (or other global for that matter) was defined?
I tried:
grep -R 'function' /usr/lib
and other similar *nix/bash-fu with only limited success and lots of annoying chaff to cull. One of you sage coders out there must have a good solution to this seemingly common scenario.
I was very surprised to not find another question on this particular pain here or in my searches of the interwebs. (I'm sure there will be angry comments if I missed one... ;-))
Thanks in advance for any tips!
Use etags/ctags from the exuberant ctags project in conjunction with an editor (emacs, vim) that understands them, or GNU GLOBAL.
Oh, and if you happen to use automake it generates a target TAGS. So no need for complicated manual calls to {c,e}tags.
Use ctags/cscope + vim/emacs
you can google for their detail use.
if you use ctags + vim, you can :
1.go to the /usr/include directory, excute ctags -f tags1 -R . generate the tags
2.generate tags for your code in your code directory ctags -f tags2 -R.
3.run :set path+=tags1,tags2 in your vim
4.under a function or marco try CTRL+]
Here is what you can do, assuming you use gcc, if not just modify it accordingly.
gcc -E myfile.c | grep '^#' | cut -f 3 -d ' ' | sort |uniq | xargs -n 1 grep -l "MYMACROORFUNCTIONNAME"
You can use Eclipse CDT. For example here is described how to setup CDT project to navigate Linux kernel source - HowTo use the CDT to navigate Linux kernel source.
vim + ctags is the way to go. You can jump to and definition of functions, global variables, macros, etc. etc.
FYI, browsing programs with tags
Also, if you want to quickly switch between .c and .h files, please refer to this blog
you can use cscope or emacs/vim + xcscope.el to do that easily. I think it's batter than ctage and etage.
Provided the correct headers are included that directly or indirectly define what you look for, most IDEs have a jump-to-definition-functionality that works.
The tags-approaches are of course nice because they don't depend on correctly included headers.

Setting and using path to data directory with GNU AutoTools

I am trying to use GNU AutoTools for my C++ project. I have written configure.ac, makefile.am etc. I have some files that are used by the program during execution e.g. template files, XML schema etc. So, I install/copy these files along the executable, for which I use something like:
abcdir = $(bindir)/../data/abc/
abc_DATA = ../data/knowledge/abc.cc
Now it copies the file correctly and My program installation structure looks somethings as follows:
<installation_dir>/bin/<executableFile>
<installation_dir>/data/abc/abc.cc
Now the problem is that in the source code I actually use these files (abc.cc etc.) and for that I need path of where these files resides to open them. One solution is to define (using AC_DEFINE) some variable e.g. _ABC_PATH_ that points to the path of installation but how to do that exactly?. OR is there any better way to do that. For example, in source code, I do something like:
...
ifstream input(<path-to-abc-folder> + "abc.cc"); // how to find <path-to-abc-folder>?
..
The AC_DEFINE solution is fine in principle, but requires shell-like variable expansion to take place. That is, _ABC_PATH_ would expand to "${bindir}/../data/abs", not /data/abc.
One way is to define the path via a -D flag, which is expanded by make:
myprogram_CPPFLAGS += -D_ABC_PATH='\"${abcdir}\"'
which works fine in principle, but you have to make include config.status in the dependencies of myprogram.
If you have a number of such substitution variables, you should roll out a paths.h file that is
generated by automake with a rule like:
paths.h : $(srcdir)/paths.h.in config.status
sed -e 's:#ABC_PATH#:${abcdir}:' $< > $#
As a side-note, you do know about ${prefix} and ${datarootdir} and friends, don't you? If not, better read them up; ${bindir}/.. is not necessarily equal to ${prefix} if the user did set ${exec_prefix}.

Best practice for dependencies on #defines?

Is there a best practice for supporting dependencies on C/C++ preprocessor flags like -DCOMPILE_WITHOUT_FOO? Here's my problem:
> setenv COMPILE_WITHOUT_FOO
> make <Make system reads environment, sets -DCOMPILE_WITHOUT_FOO>
<Compiles nothing, since no source file has changed>
What I would like to do is have all files that rely on #ifdef statements get recompiled:
> setenv COMPILE_WITHOUT_FOO
> make
g++ FileWithIfdefFoo.cpp
What I do not want to is have to recompile everything if the value of COMPILE_WITHOUT_FOO has not changed.
I have a primitive Python script working (see below) that basically writes a header file FooDefines.h and then diffs it to see if anything is different. If it is, it replaces FooDefines.h and then the conventional source file dependency takes over. The define is not passed on the command line with -D. The disadvantage is that I now have to include FooDefines.h in any source file that uses the #ifdef, and also I have a new, dynamically generated header file for every #ifdef. If there's a tool to do this, or a way to avoid using the preprocessor, I'm all ears.
import os, sys
def makeDefineFile(filename, text):
tmpDefineFile = "/tmp/%s%s"%(os.getenv("USER"),filename) #Use os.tempnam?
existingDefineFile = filename
output = open(tmpDefineFile,'w')
output.write(text)
output.close()
status = os.system("diff -q %s %s"%(tmpDefineFile, existingDefineFile))
def checkStatus(status):
failed = False
if os.WIFEXITED(status):
#Check return code
returnCode = os.WEXITSTATUS(status)
failed = returnCode != 0
else:
#Caught a signal, coredump, etc.
failed = True
return failed,status
#If we failed for any reason (file didn't exist, different, etc.)
if checkStatus(status)[0]:
#Copy our tmp into the new file
status = os.system("cp %s %s"%(tmpDefineFile, existingDefineFile))
failed,status = checkStatus(status)
print failed, status
if failed:
print "ERROR: Could not update define in makeDefine.py"
sys.exit(status)
This is certainly not the nicest approach, but it would work:
find . -name '*cpp' -o -name '*h' -exec grep -l COMPILE_WITHOUT_FOO {} \; | xargs touch
That will look through your source code for the macro COMPILE_WITHOUT_FOO, and "touch" each file, which will update the timestamp. Then when you run make, those files will recompile.
If you have ack installed, you can simplify this command:
ack -l --cpp COMPILE_WITHOUT_FOO | xargs touch
I don't believe that it is possible to determine automagically. Preprocessor directives don't get compiled into anything. Generally speaking, I expect to do a full recompile if I depend on a define. DEBUG being a familiar example.
I don't think there is a right way to do it. If you can't do it the right way, then the dumbest way possible is probably the your best option. A text search for COMPILE_WITH_FOO and create dependencies that way. I would classify this as a shenanigan and if you are writing shared code I would recommend seeking pretty significant buy in from your coworkers.
CMake has some facilities that can make this easier. You would create a custom target to do this. You may trade problems here though, maintaining a list of files that depend on your symbol. Your text search could generate that file if it changed though. I've used similar techniques checking whether I needed to rebuild static data repositories based on wget timestamps.
Cheetah is another tool which may be useful.
If it were me, I think I'd do full rebuilds.
Your problem seems tailor-made to treat it with autoconf and autoheader, writing the values of the variables into a config.h file. If that's not possible, consider reading the "-D" directives from a file and writing the flags into that file.
Under all circumstances, you have to avoid builds that depend on environment variables only. You have no way of telling when the environment changed. There is a definitive need to store the variables in a file, the cleanest way would be by autoconf, autoheader and a source and multiple build trees; the second-cleanest way by re-configure-ing for each switch of compile context; and the third-cleanest way a file containing all mutable compiler switches on which all objects dependant on these switches depend themselves.
When you choose to implement the third way, remember not to update this file unnecessarily, e.g. by constructing it in a temporary location and copying it conditionally on diff, and then make rules will be capable of conditionally rebuilding your files depending on flags.
One way to do this is to store each #define's previous value in a file, and use conditionals in your makefile to force update that file whenever the current value doesn't match the previous. Any files which depend on that macro would include the file as a dependency.
Here is an example. It will update file.o if either file.c changed or the variable COMPILE_WITHOUT_FOO is different from last time. It uses $(shell ) to compare the current value with the value stored in the file envvars/COMPILE_WITHOUT_FOO. If they are different, then it creates a command for that file which depends on force, which is always updated.
file.o: file.c envvars/COMPILE_WITHOUT_FOO
gcc -DCOMPILE_WITHOUT_FOO=$(COMPILE_WITHOUT_FOO) $< -o $#
ifneq ($(strip $(shell cat envvars/COMPILE_WITHOUT_FOO 2> /dev/null)), $(strip $(COMPILE_WITHOUT_FOO)))
force: ;
envvars/COMPILE_WITHOUT_FOO: force
echo "$(COMPILE_WITHOUT_FOO)" > envvars/COMPILE_WITHOUT_FOO
endif
If you want to support having macros undefined, you will need to use the ifdef or ifndef conditionals, and have some indication in the file that the value was undefined the last time it was run.
Jay pointed out that "make triggers on date time stamps on files".
Theoretically, you could have your main makefile, call it m1, include variables from a second makefile called m2. m2 would contain a list of all the preprocessor flags.
You could have a make rule for your program depend on m2 being up-to-date.
the rule for making m2 would be to import all the environment variables ( and thus the #include directives ).
the trick would be, the rule for making m2 would detect if there was a diff from the previous version. If so, it would enable a variable that would force a "make all" and/or make clean for the main target. otherwise, it would just update the timestamp on m2 and not trigger a full remake.
finally, the rule for the normal target (make all ) would source in the preprocessor directives from m2 and apply them as required.
this sounds easy/possible in theory, but in practice GNU Make is much harder to get this type of stuff to work. I'm sure it can be done though.
make triggers on date time stamps on files. A dependent file being newer than what depends on it triggers it to recompile. You'll have to put your definition for each option in a separate .h file and ensure that those dependencies are represented in the makefile. Then if you change an option the files dependent on it would be recompiled automatically.
If it takes into account include files that include files you won't have to change the structure of the source. You could include a "BuildSettings.h" file that included all the individual settings files.
The only tough problem would be if you made it smart enough to parse the include guards. I've seen problems with compilation because of include file name collisions and order of include directory searches.
Now that you mention it I should check and see if my IDE is smart enough to automatically create those dependencies for me. Sounds like an excellent thing to add to an IDE.