[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: