C To C++ Converter - Table of Contents


Node:Top, Next:, Previous:(dir), Up:(dir)

This documentation is for: ctocpp, version 1.4.0
Mail: webmaster@scriptol.com.
Home page: https://www.scriptol.com/
Alternate page: https://www.scriptol.fr/


Node:Overview, Next:, Previous:Top, Up:Top

Overview

These scripts allow to convert a C file or a whole C project to C++. They should be used mainly by someone that want to convert big files, or several projects, as some time is required to master the tool.

I have written it because I did not have 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 and convert a project is:
ctocpp ... some arguments ...

If you want to convert single files only, use directly each script instead.
They are in the c2cpp sub-directory, and under Unix, in /usr/local/c2cpp unless you have installed them elsewhere.


Node:Requirements & conventions, Next:, Previous:Overview, Up:Top

Requirements & conventions

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);


Node:How it works, Next:, Previous:Requirements & conventions, Up:Top

How it works

The conversion process is accomplished in several steps according to the options:
1) Use -l to build the list of all sources automatically.
2) Use -i to complete the header files.
3) Use -a to build the new list of header files.
4) Use -c 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.
5) Use -p 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 then a makefile to build your new C++ program. This depends the compiler you use and is not covered here.


Node:Tools, Next:, Previous:How it works, Up:Top

Tools

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.
- mover.py: translates a project from a directory to another one.
- search.py: is a general purpose search-replace tool for strings or identifiers.
Some other .py files are modules called by the named scripts.


Node:Mover, Next:, Previous:Tools, Up:Top

Mover

Mover - Project Translator

This program changes directories of files used by a C project and updates the include statements. Files are moved from one directory to another one, from several directories to several other ones, or from several directories to a single one. A text as "../" may be replaced by an absolute path and conversely.

The syntax is:

mover mainfile.c origpath@destpath [ origpath@destpath ]*

The source file it the one that holds the main function.
It is followed by a list of couples:
original path @ destination path
Example:
c:\gui @ t:\ide

All files of the project, (from which the main source is dependent), will be moved according to the couple given at command line.
The #include statements will be updated according to the changes in directories.
The files may be grouped into an unique directory:
mover mainfile.c \lister@\newlister \gui@\newlister

Warnings:
- Under Windows the project and mover must stand on the same disk.
- Take care to the \ and / symbols in paths, according to the operating system.


Node:Search, Next:, Previous:Mover, Up:Top

Search

Search and Replace

This program searches and (optionaly) replaces either an identifier or a string, in a file, or in a set of files.
Regular expressions are not supported.

This searches texts in a file, or in a set of files matching a pattern. The pattern may contain wilcards which are those of MS-DOS and Unix: * and ?

The search can be performed case-sensitive or not. One can search for identifiers in source, or any string in any ASCII text.

By changing the "delimiters" string in the source, one can change definition of what is identifier.
The current setting doesn't include "#" among delimiters.

The syntax is:

search [options] searching [replacing] filename

1) Filename may contain wildcards, example:
*.c
name.*
name?.py

2) If the replacing text is omitted, a simple search is performed.

3) Options are those:

-i case-insensitive for searched identifier.
-w Windows mode, case-insensitive for filename. Defaults are case-sensitive.
-c search for identifiers in code. The default is search for strings.
The string may contain space and must be inclosed inside "". Space is a delimiter, therefore identifiers always are single words.
-q quiet mode, don't display when replacing. Default is display.
-h displaying help.
-v displaying version.

4) Multiple options are packed into a single string as:
-ifcq

Removing strings from a text file may be performed by replacing them by a blank space. Example:
search -w "searched" " " filename


Node:Limitations, Next:, Previous:Search, Up:Top

Limitations


Node:General restrictions, Next:, Previous:Limitations, Up:Limitations

General restrictions

- 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!


Node:Make list, Next:, Previous:General restrictions, Up:Limitations

Make list

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"


Node:Make header, Next:, Previous:Make list, Up:Limitations

Make header

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.


Node:Make class, Next:, Previous:Make header, Up:Limitations

Make class

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.


Node:Step by step, Next:, Previous:Make class, Up:Top

Step by step

To convert a whole project, a single command is used repetively, with different options and arguments:

COMMAND: ctocpp

The arguments may be:

- the full path of the main file, (the one that holds the "main" function).
- the name of a filename that holds the list of sources.
- the name of a filename that holds the list of headers.
- a couple of paths separated by the @ symbol, for the move command only.

When the scripts are used directly and not from the ctocpp command, the filename of a list of file must be prefixed by the @ symbol, when it must be read, not when it must be created.


Node:Moving the files, Next:, Previous:Step by step, Up:Step by step

Moving the files

Step 1: Move the files. This is optional.

COMMAND: ctocpp -m 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.


Node:Making a list, Next:, Previous:Moving the files, Up:Step by step

Making a list

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.


Node:Verify headers, Next:, Previous:Making a list, Up:Step by step

Verify headers

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.


Node:List of headers, Next:, Previous:Verify headers, Up:Step by step

List of headers

Step 4:
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.


Node:Generating classes, Next:, Previous:List of headers, Up:Step by step

Generating classes

Step 5:
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.


Node:Propagating changes, Next:, Previous:Generating classes, Up:Step by step

Propagating changes

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 -p 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.


Node:Example, Next:, Previous:Propagating changes, Up:Top

Example

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 https://www.scriptol.com)

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: allhead /cdnew/listit.c /cdnew/cdlist.hpj
Step 5: mkclass @/cdnew/cdlist.prj
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++)


Node:Index, Previous:Example, Up:Top

Index

Copyright 2001-2008 © Denis Sureau https://www.scriptol.com/