

                      C to C++ translator
              Free program (c) 2001 by D.G. Sureau
                    webmaster@scriptol.com
                         -*=*=*=*=-


 For Windows, Linux and others, as Python is universal.
 Requires the python language (www.python.org) installed.
 It is very easy to install both under Windows or Linux.
 Available freely for any personal or commercial usage
under the GPL license: in brief, if you made any change
to the program, you must send them to me.

  I   What it is
 II   Requirements & conventions
III   How it works
 IV   Other tools
  V   Limitations
 VI   Detailed usage
      Example: CDList


I What it is


 These scripts allow to convert a C file or a whole C project
into C++.
 I have written it because I had no found a such tool over
the Net.
 These are simple scripts, anyway. To work, they require the C
source written with a good programming style: one statement
per line is required in most case.
  void func() {  x = 5; }   should be written rather as
  void func()
  {
    x = 5;
  }
 Before to start, you need to mark as "static", any variable
or function you want not to be included as class members. This
is required for variables used by inlined assembler code.

 The script build classes, and global variables will become
members of the classes, functions will become methods.

 Being an all static system at this stage, the new program
is not very different of the C one, apart to be more readable.
 But it is a basis to add new classes and methods.


II Requirements


 To convert your C project into a C++ one, you need for:
 - Some files with ".c" extensions.
 - The python interpreter installed. (Get it at www.python.org)
   Versions are available for Windows, Linux and Mac.
 - The files below, in the current archive normally:

   wstring.py      pattern.py       lexer.py
   mover.py        mklist.py        mkheader.py
   mkclass.py      allhead.py       mkcpp.py
   iscomp.py

   Under Windows only:

   convert.bat     mover.bat         mklist.bat
   mkheader.bat    mkclass.bat       allhead.bat
   mkcpp.bat

 Conventions
 - C sources must have the .c extension
 - C headers must have the .h extension
 - a variable with the "static" modifier remain global
   and doesn't become a class member.
   (class attributes are declared as static from variable
   not declared as static, because static for C++ class is
   a different thing).


III How it works


 The conversion requires several passes:
1) Use mkheader.py to produces correct header files.
2) Use mkclass.py to create the C++ classes.
   The name of a class is the name of the C file,
   all variables and functions will be declared static.
   You can change manually the class produced into ".hpp" files.
3) Use mkmethod.py to produce ".cpp" files inside which
   all c functions are transformed into methods according to
   the class declaration.
   Global variables are removed from the .cpp files.
4) Use mkcpp.py to transform any C references of variables and
   functions to C++ equivalents references to attributes and
   methods, according to the classes declarations.

 You need also a makefile to build your C++ program. This
depends the compiler you use and is not covered here.
 A sample batch is included that works with bcc 5.5



IV Other tools


- makehead.py
  may also be used as a standalone tool to make and update
  c header files.
- search.py
  is a general purpose search-replace tool to process strings
  or identifiers inside text files.
- other .py files not named above are modules called
  by the named scripts.



V - Restrictions and limitations
--------------------------------

general restrictions:
--------------------
- The program assumes the C code is written with a good
  programming style. What is unreadable for an human will
  be unreadable for the program too.

- Define statements used in code must be moved to header
  file, they are processed in some cases only by my scripts.

- The step 3 and 4 are the more complex ones. If the
  conversion don't work, perform them manually, they are
  also the less fastidious ones. The other ones should work
  without problem, and luckily, what they do is the more
  annoying.

mklist.py restriction:
---------------------
- If your project uses a list of files as the ones of Turbo C,
you don't need for mklist.
 Mklist is able to build this list providing that all functions
have a prototyp in header file and this header file is included
in each source using the function. Otherwise you have to complete
the list.
- The #include statements should use the "" enclosures for your
header files and the <> ones, for external libraries.
 For example:    #include <stdlib.h>
                 #include "myheader.h"

mkheader.py restrictions:
------------------------
- The script doesn't manage conditional compilation.
  Statements as #if or #ifdef are not managed when building
  the header file.

- Functions may take macro arguments as the FILE one.
  This can be a problem inside an header file. Such problem is
  already solved if each function has a prototyp in the original
  source, but this is no always the case, as old compiler allows
  to omit them.
  When such problems are encoutered in producing the header file,
  change manually the file.

mkclass.py:

- The name automatically choosen, that of the file, may conflict.
  A function with the same name will be considered as a constructor.


VII Detailed usage

------------------- Print the text below -------------------

            C to C++ Conversions step by step

------------------------------------------------------------
Step 1: Move the files. This is optional.

 type:  python mover.py mainfile.c olddir:newdir [olddir:newdir]
 ----
- mainfile.c is the file that holds the main() function.
- olddir is a directories where the files are stored
- newdir is the new location.
- several old:new couples are required if the project stays
inside several directories.
 You can move all directories into a single one.
N.B;: If you move the files with a file manager, the #include
statement will not be updated.

------------------------------------------------------------
Step 2:  Make the project list with mklist.py

 type:  python mklist.py  mainfile.c prjlist
 ----
- mainfile.c is the file that holds the main() function.
- prjlist is the name of the file that will contains the
list of all .c sources of the project (you choose a name
for it).
 It will be overwritten without prompting.

------------------------------------------------------------
Step 3: Make declarations inside headers, matching the
definitions inside sources.

 C compiler are less restrictive than C++ one, a function
can be used without prototypes.
 To update your sources to C++ rules, use mkheader.py

 type:   python mkheader.py @prjlist
 ----
- do not forget the @ before the project's filename.

------------------------------------------------------------
Step 4:
 If you want to define you own classes, skip this step.
mkclass allows to make a class from variables and prototypes
from an header file. If produces a new .hpp file and doesn't
change the previous header.

 type:   python mkclass.py @prjlist
 ----
- Do not forget the @ symbol before the project's filename.
- If a function has name that is that of the file, it will
  be considered as a constructor. The class name must be changed.

 When all C++ headers are created you may change the default
classes names or move their members from class to class if
you want.
 If a method has the same name that the class, you must to
rename the class, as the name is reserved to a constructor.
 
------------------------------------------------------------
Step 5:
 Now you need the list of all header files.
 This is not the same that the list of sources, as the
project may use header to include with no corresponding
source.

 type:  python allhead.py mainfile.c headlist
 ----
- Headlist if the name of the file to create, that
will hold all header filenames. No symbol @ at this stage
(It is used to differentiate a source from a list of files).
- The file is overwritten without prompting.

------------------------------------------------------------
Step 6:
 The last step produces a full set of C++ files with .cpp
extensions, from .c and .hpp files.
- Function are transformed in methods.
- Global variables are made static and integrated into class declarations.
- Call of functions are replaced by call of methods.
- Global variables references are replaced by references to members.

 type:   python mkcpp.py @prjlist @headlist
 ----
- Prjlist is the name of the file that hold all .c sources
in the project. The symbol @ prefixes the name.
- Headlist is a file that holds all .h headers. Symbol @ before it.

------------------------------------------------------------
Now you are ready to compile your C++ project.

N.B.: If you omit the "@" symbol in front of a filename
when required, the script will process the file itself,
not a list of files. This allows to convert a single file.


Example: CDList


 The scripts are installed into the \ctocpp directory.
 The CDList files are in the \cdwin directory.
 The program use a personal GUI library, in the \gui directory.
 The main function is inside the listit.c file.
 I choose to move all necessary file into the \cdnew directory
and give the new project file the "cdlist" name:

 From the \ctocpp directory:
 Step 1: python mover.py \cdwin\listit.c \gui:\cdnew \cdwin:\cdnew
 Step 2: python mklist.py \cdnew\listit.c \cdnew\cdlist.prj
 Step 3: python mkheader.py  @\cdnew\cdlist.prj
 Step 4: python mkclass.py @\cdnew\cdlist.prj
 Step 5: python allhead.py \cdnew\listit.c \cdnew\cdlist.hpj
 Step 6: python mkcpp.py @\cdnew\cdlist.prj @\cdnew\cdlist.hpj

 N.B.:
- the @ symbol is used when the file is a list of files and
when it is read, not when it is created.
- under Windows, python xxx.py may be replaced by xxx.bat
- under Windows, a single batch file, "convert.bat" performs the
steps 2 to 6:
 I type:    convert.bat  \cdnew\listit.c \cdnew\cdlist

 This is not recommend, as you may have to rename classes
automatically created.
 The new C++ project may be compiled with the cdcpp.mak
makefile for Turbo C++ 3.1  in the cdwin directory.
 Delete the .c files and type:  make -fcdcpp.mak

