This documentation is for: ctocpp
, version 1.2.0
Mail: webmaster@scriptol.com.
Home page: http://www.scriptol.com/
Alternate page: http://scriptol.tuxfamily.org/
These scripts allow to convert a C file or a whole C project to C++.
I have written it because I have not found a such tool over the Net.
Since I have written the project before Scriptol was available, it
is written in Python and you need to install the Python interpreter
to run the scripts.
These are simple scripts, anyway. They require C sources written
with a clear programming style: one statement per line is
required in most case. Programs are available over the web to format
properly C sources.
Before to start, you need to mark as "static", any variable or function
you want not being converted to class members.
The scripts build classes, and global variables will become members of
the classes, functions will become methods.
The command to run the program is:
python ctocpp.py ... some arguments ...
but in this manual, I simplify by:
ctocpp ... some arguments ...
Being an all static system at this stage, the new C++ program is not very
different of the C one, apart to be more readable. But this is a basis to add
new classes and methods or to integrate it in a larger C++ project.
For Windows, Linux and others, as Python is universal.
Requires the python interpreter (www.python.org) installed.
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)
- The files below, from the current archive:
wstring.py pattern.py mklist.py lexer.py mover.py
mkclass.py allhead.py iscomp.py mkcpp.py mkheader.py
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 (nothing to do with a C++ static member!
class attributes are declared as static from variable not
declared as static, because static for C++ class is a different
thing).
- If a declaration is splitted, parts must be ended by a comma.
Example:
mydecl(int x,
int y);
The conversion process is accomplished in a single passe
if no option is given, or in several steps according to the options:
1) Use -list to build the list of all sources automatically.
2) Use -include to complete the header files.
3) Use -class 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.
4) Use -all to build the new list of header files.
5) Use -prop 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.
References to variables and functions are replaced by to C++
equivalents references to attributes and methods.
You need also a makefile to build your C++ program. This
depends the compiler you use and is not covered here.
Some tools here included may be used for a general purpose, type the name
of the tool without parameter to get the usage. The main ones are:
- mkhead.py
may be used as a standalone tool to make and update
c header files. Required here for multi-lines declarations.
- search.py
is a general purpose search-replace tool to process strings
or identifiers inside text files.
- mover.py
translates a project from a directory to another one. Changes
#include statements.
Some .py files are modules called by the named scripts.
- The program assumes the C code is written with a good
programming style. What is hard to read for an human will
be hard to parse for the program too.
- Define statements used in code must be moved to header
file, they are processed only in some cases by the scripts.
- The step -class is the more complex ones. If the conversion
doesn't work, then perform it manually instead, it is also
the less fastidious ones. The following -prop should work without
problem, and luckily, what it does is also the more annoying part!
Limitations for the -list command.
- If your project uses a list of files as the ones of Turbo C,
you don't need for mklist.
The program is able to build this list providing that all functions
have a prototype 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"
Limitations for the -include command.
- 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 prototype 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.
Limitations for the -class command.
- The name automatically choosen, that of the file, may conflict.
A function with the same name that the file will has same name
that a class and will be considered as a constructor.
If your source are are saved and if you are sure your code is
compatible with C++ conventions that are more restrictive than
C ones, but compatible with it, you can type a single command:
COMMAND: ctocpp mainfile.c projectlist
In other cases, process step by step as below...
Step 1: Move the files. This is optional.
COMMAND: mover 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
statements will not be updated.
Step 2: Make the project list with mklist.py
COMMAND: ctocpp -l 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
COMMAND: ctocpp -i mainfile.c projectlist
- do not forget the @ before the project's filename.
Step 4:
If you want to define you own classes, skip this step.
-class or 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.
COMMAND: ctocpp -c mainfile.c projectlist
- 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.
COMMAND: ctocpp -a mainfile.c projectlist
- 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.
COMMAND: ctocpp -c mainfile.c projectlist
- 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.: When you use a sub-program directly, 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 (available at http://scriptol.tuxfamily.org)
The / symbol is inverted for Windows.
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:
You can type simply: ctocpp \cdnew\listit.c \cdnew\cdlist
But this is not recommend, as you may have to rename classes
automatically created.
Or you can perform detailed steps:
From the /ctocpp directory, using the scripts directly:
Step 1: mover /cdwin/listit.c /gui:/cdnew /cdwin:/cdnew
Step 2: mklist /cdnew/listit.c /cdnew/cdlist.prj
Step 3: mkheader @/cdnew/cdlist.prj
Step 4: mkclass @/cdnew/cdlist.prj
Step 5: allhead /cdnew/listit.c /cdnew/cdlist.hpj
Step 6: mkcpp @/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.
Delete the .c files and type: make -fcdcpp.mak
(makefile for Turbo C++)