automatic conversion to new libstdc++-v3
hello
I have tried to prepare a tool that tries to automatically convert
c++ code to use the new library libstdc++-v3, and then gcc-v3.0
This sh script tries to solve the problem shown in
http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/porting-howto.html
as suggested in section 1.1.4
Usage: gcc-3.0-ize [ --undo ]
In libstdc++-v3 the string class has been moved to std::string, and
so for other classes.
gcc-3.0-ize tries to automatically adapt your source code; to this end,
gcc-3.0-ize patches the c++ code and the 'configure.in' file.
gcc-3.0-ize adds AC_LIBSTDCXX_STRING to configure.in:
this autoconf macro checks if 'string' is in base namespace or in 'std::'
and it defines NS_STD in config.h
and replaces NS_THESTD in *.in accordingly.
See gcc-3.0-ize.m4 for details.
The header files FILE.h that will be installed by 'make install' are
changed to FILE.h.in so that they will be preprocessed accordingly
by 'configure'.
All other c++ files are patched directly:
gcc-3.0-ize changes the c++ code to use the preprocessor variable NS_STD.
It also deletes 'bad_alloc' that is not a valid signal any more.
Currently gcc-3.0-ize handles the following classes:
string basic_string deque queue list cout cin ios basic_streambuf streambuf stream
It is quite easy to add other classes. Please tell me which I am missing.
gcc-3.0-ize backups any file into file.nogcc-3.0 so that
gcc-3.0-ize --undo will safely undo any change to your project.
to use, put both attachments in a same directory.
have fun
a.
--
A Mennucc
"È un mondo difficile. Che vita intensa!" (Renato Carotone)
#!/bin/sh
# this program is copyright (C) from aug 2000 on
# by A Mennucc1 <debian@tonelli.sns.it>
#
# license: GNU General Public License
# To have a copy of the license, write to the Free Software
# Foundation, 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
b=`basename $0`
names='string basic_string deque queue list cout cin ios basic_streambuf streambuf stream'
BACKUPEXT=.nogcc-3.0
if [ "$1" == "--help" -o "$1" == "-h" ]; then
cat <<EOF
Usage: $b [ --undo ]
In libstdc++-v3 the string class has been moved to std::string, and
so for other classes.
$b tries to automatically adapt your source code; to this end,
$b patches the c++ code and the 'configure.in' file.
$b adds AC_LIBSTDCXX_STRING to configure.in:
this autoconf macro checks if 'string' is in base namespace or in 'std::'
and it defines NS_STD in config.h
and replaces NS_THESTD in *.in accordingly.
See $b.m4 for details.
The header files FILE.h that will be installed by 'make install' are
changed to FILE.h.in so that they will be preprocessed accordingly
by 'configure'.
All other c++ files are patched directly:
$b changes the c++ code to use the preprocessor variable NS_STD.
It also deletes 'bad_alloc' that is not a valid signal any more.
Currently $b handles the following classes:
$names
It is quite easy to add other classes.
$b backups any file into file$BACKUPEXT so that
$b --undo will safely undo any change to your project.
EOF
exit
fi
sednames=`echo "$names" | sed 's/ /\\\|/g'`
egrepnames=`echo "$names" | sed 's/ /|/g'`
#echo "$grepnames"
#exit
DO=
c=configure.in
[ -r configure.ac ] && c=configure.ac
if [ "$1" == "--undo" -o "$1" == "-u" ]; then
for f in `find -type f -name "*$BACKUPEXT" | sed "s/$BACKUPEXT$//" ` ; do
$DO mv -v $f$BACKUPEXT $f
[ -r $f.in ] && $DO rm -v $f.in
done
#[ -r $c$BACKUPEXT ] && $DO mv -v $c$BACKUPEXT $c
exit
fi
if [ "$1" == "--diff" ]; then
for f in `find -type f -name "*$BACKUPEXT" | sed "s/$BACKUPEXT$//" ` ; do
if [ -r $f.in ] ; then
$DO diff -su $f$BACKUPEXT $f.in
else
$DO diff -su $f$BACKUPEXT $f
fi
done
exit
fi
[ "$1" ] && { $0 --help ; exit 1 ; }
if [ -r $c$BACKUPEXT ] ; then
echo $b: sorry $c$BACKUPEXT exists, cant run twice. Use -u to undo
exit 1
fi
if [ ! -r $c ] ; then
echo $b: sorry this program works only for projects using autoconf/automake
exit 1
fi
#this is also a sort of lock
$DO mv $c $c$BACKUPEXT
f=`tempfile`
sanity () {
if [ -r $h ] && egrep -q "$egrepnames" $h ; then
if [ -r $h$BACKUPEXT ] ;then
echo $b: backup of $d/$h exists already as $d/$h$BACKUPEXT, cant proceed
exit 1
fi
if [ -r $h.in ] ;then
echo "$b: $d/$h.in exists already : cant add 'std::string' support"
else
echo $b: backup of $d/$h in $d/$h$BACKUPEXT
$DO mv $h $h$BACKUPEXT
echo $b: creating $d/$h$e
$DO echo "/* this program was patched by $b */" > $h$e
[ "$e" == '' ] && $DO echo '#include <config.h>' >> $h$e
#please add here other handlers
$DO sed -e '/^[^#]/s/\([^a-zA-Z0-9_:]\)\('"$sednames"'\)\(\>\|[^a-zA-Z0-9_]\)/\1'$z'::\2\3/g' \
-e '/^[^#]/s/^\('"$sednames"'\)\(\>\|[^a-zA-Z0-9_]\)/'$z'::\1\2/g' \
-e '/^[^#]/s/\([^a-zA-Z0-9_]\)bad_alloc *,/\1/' \
$h$BACKUPEXT >> $h$e || true
[ "$e" == '.in' ] && $DO echo $d/$h >> $f
fi
else
echo $b: $d/$h does not need processing
fi ;
}
for i in ` find -name Makefile.am ` ; do
d=` dirname $i `
pushd "$d" > /dev/null
z='@NS_THESTD@'
e='.in'
for h in `awk '! /\\$/{print} /\\$/{sub(/\\$/,"");printf($0)}' Makefile.am |\
grep include_HEADERS | cut -d= -f2- ` ; do
sanity
done
z='NS_STD'
e=''
#awk '! /\\$/{print} /\\$/{sub(/\\$/,"");printf($0)}' Makefile.am |\
# grep _SOURCES | cut -d= -f2-
for h in * ; do
{ case $h in
*.C) sanity ;;
*.cc) sanity ;;
*.h) sanity ;;
esac ; }
done
popd > /dev/null
done
if [ ! -r acinclude.m4 ] || ! grep -q AC_LIBSTDCXX_STRING acinclude.m4 ; then
echo $b: adding AC_LIBSTDCXX_STRING to acinclude.m4
[ -r acinclude.m4 ] && $DO cp acinclude.m4 acinclude.m4$BACKUPEXT
cat $0.m4 >> acinclude.m4
fi
a=''
if grep -q AC_LIBSTDCXX_STRING $c$BACKUPEXT ; then
echo $b: it seems that this project already uses AC_LIBSTDCXX_STRING
else
a=AC_LIBSTDCXX_STRING
fi
ff=` tr '\n' ' ' < $f `
$DO awk 'BEGIN{b="'"$ff"'"};
/AC_OUTPUT/{print "'$a'";\
sub(/AC_OUTPUT *\(/, ("AC_OUTPUT(" b " ") );}\
//{print}' $c$BACKUPEXT >$c
cat <<EOF
$b: try the new project, run :
./autogen.sh ; ./configure [options] ; make
if you are completely satisfied, you may delete all
the files ending by $BACKUPEXT
EOF
rm $f
dsl this macro checks if string is in in base namespace or in std::
dsl it defines NS_STD in config.h
dsl and replaces NS_THESTD in *.in accordingly
AC_DEFUN(AC_LIBSTDCXX_STRING,
[
AC_MSG_CHECKING("if string namespace is in std::string in libstdc++")
AC_TRY_COMPILE([
#undef const
#include <string>
],[
std::string thestring("pippo");
],[
AC_MSG_RESULT(yes)
NS_THESTD="std"
],[
AC_MSG_RESULT(no)
NS_THESTD=""
])
AC_DEFINE_UNQUOTED(NS_STD, $NS_THESTD,
[it is 'std' or '' so that NS_STD::string will always work])
AC_SUBST(NS_THESTD)
])
Reply to: