Introduction
This program generates C or C++ programs that parse command-line arguments and display the parsed values. The purpose of this program is to save typing and allowing the rapid creation of programs that can be modified for some intended purpose.
The program is intended to save typing when writing a C or C++ console program. While the program produces code that runs, it is expected that the user will want to modify the generated code.
A folder is created with the same name as the base name of the program name passed on the command line and the generated code is created in this folder.
Update: February 11, 2019
A new upload now generates Visual Studio 17 (and 15?) build files.
Former file get_arguments_function_creator.py is replaced with get_arg_info_creator.py. The new code generates a parser that will allow combining boolean options on a line, i.e., in the generated C or C++ program, instead of having to do "-a -b -c
" on the command line, the user could instead use the argument, "-abc
".
The code also has more features, which can be seen by accessing the help by typing:
python make_c_cpp_prog.py -h
Background
The program was written with Python version 2.7, but it should also run with Python 2.6. The program is made up of the following files:
make_c_cpp_prog.py | The main program file that parses the input arguments and calls other python files to create the generated files. |
c_cpp_program_creator.py | The main code generator, which creates the C or C++ code main file that parses the arguments and displays them. |
carginfo.py | Stores type, name, and default value information for the generated program arguments. |
program_properties.py | Stores whether to generate a C or C++ program and other program attributes. |
cpp_keyword_checker.py | Identifies if a name is a C++ keyword. Even if C code is being generated, the latest C++ 11 keywords are prohibited. |
makefile_creator.py | Creates a Linux Makefile. |
get_arg_info_creator.py | Creates file get_arg_info.c and get_arg_info.h, which are used to parse the C or C++ arguments. |
platform_os_creator.py | Creates header file platform_os.h, which is used to define platform and operating specific symbols. |
vs_build_creator.py | Creates Visual Studio build files. |
example_program.bat | This is not part of the program. This Windows TM batch file runs the program to produce a sample program. The user must supply a file name after the batch file name. |
I have been compiling recently on Windows using Visual Studio. Linux used to work, and while I expect no issues, it is possible that file platform_os.h and the Makefile might need some tweaking for Linux. I will update the code if there are any issues.
Using the Code
Usage
python make_c_cpp_prog.py <program name> <parameter arguments>
Version 1.5
This program creates a C or C++ command line program with optional argument parsing and also creates program build files for both Windows(TM) and Linux.
The program command line has the form:
python make_c_cpp_prog.py <program_name> [parameter 1] [parameter 2} ... [parameter N]
[-u | --unicode] [-s | --static]
or
python make_c_cpp_prog.py [-h | --help]
The form <x>
indicates x
is required, and the form [y]
indicates that y
is optional.
Program Name
The <program_name>
parameter ends with either the file extension ".c", for a C program, or either ".cpp" or ".cc" for a C++ program.
Parameter Arguments
Each generated-program argument parameter is a comma delimited list with the form:
<var_name[="initial_value"]>[,var_type][,-short_switch][,--long_switch]
The variable name must be first. The var_type
, and switch
parameters can be in any order.
Parameter Arguments - About var_name
The variable name must always be the first item specified for each parameter. The variable name may only contain letters of the English alphabet or digits, or the underscore character. The first letter of a variable name cannot be a digit character.
Optional parameters can specify a default value. To define a default value, then follow the variable name with an equal sign and the default value. For string
s, if the default value contains whitespace, then the default value must be bracketed by double quote characters.
The only valid values for a Boolean parameter are false and true
.
For C programs, these will be changed to "FALSE
" and "TRUE
".
Parameter Arguments - About var_type
The var_type
specifier can be one of the following characters.
If no initial_value
is specified for each of these types, the indicated initial default value is used.
s
- A string
argument. A string
defaults to the empty string
. i
- An integer argument. Defaults to 0
. f
- A floating point argument. Defaults to 0.0F
. d
- A double-precision floating point argument. Defaults to 0.0
. b
- A Boolean argument. Defaults to FALSE
.
If the var_type
is not specified, then the var_type
defaults to 's
', which indicates a string
argument.
Parameter Arguments - Switches
An initial dash character indicate a switch
. A single dash character indicates a short, or single character, switch
name.
Two initial dash characters specify a long-name switch
.
A short-name switch
and a long-name switch
may both be specified.
The "-h"
and "--help"
switches are implemented automatically and should not be specified as switch
parameters.
Parameter Arguments - About Boolean Parameters
A Boolean parameter, with var_type
'b
', is typically used as an optional switch
parameter. Using the switch
for a Boolean parameter in the generated program results in the variable name for the Boolean argument being set to the opposite of the initial_value
.
Code Generation Control Options
The following python program options control compiler and linker settings for the generated build files. Currently these options only affect the generated Windows(TM) Visual Studio 15 project file.
The short forms of switches that control Boolean options can be combined, so "-u -s
" may be replaced with "-us
". (The short forms of Boolean options in the generated C or C++ code can also be combined).
-u
| --unicode
- Specifies to use Unicode characters.
The default is to use ASCII.
-s
| --static
- Specifies to use a static system runtime libraries.
The default is to use Dynamic Link Librarys (DLLs).
-h
| --help
- Print this help text and exit.
Example Command Lines
python make_c_cpp_prog.py foo.cpp -us alpha,i beta,f file_name gamma,-g,--gm,b
This command line generates a program named "foo.cpp".
The first argument indicates to build with Unicode characters, and specifies to link with the static
runtime library. The generated program takes an integer parameter named "alpha"
, a floating point parameter named "beta"
, then a string
parameter named "file_name"
, and finally, an optional parameter named "gamma"
that is a Boolean value that is only "true"
if either the '-g
' switch or the '--gm
' switch is specified on the command line for the generated program.
python make_c_cpp_prog.py foo file_name the_name="abc",-n,--name
This command line creates a program named "foo.c" that takes a single optional argument named "file_name"
and an optional parameter named "the_name"
. If the optional parameter is not specified on the command line, then variable "the_name"
will default to the value "abc
".
Created FIles
<program name>.c | For C++, the file extension will be either ".cc" or ".cpp" |
platform_os.h | A header file with platform and operating specific definitions |
get_arg_info.h | The header file for the 'get_arg_info ' function |
get_arg_info.c | The implementation file for the 'get_arg_info ' function |
<base program name>.sln | A Visual Studio 2015 solution file |
<base program name>.vcxproj | A Visual Studio 2015 project file |
<base program name>.vcxproj.filters | A Visual Studio 2015 project filter file |
Makefile | A Linux Makefile |
The contents of the individual program files that are produced are too large to list here.
Points of Interest
This code evolved over time. If I were to write it again, I might write it differently, but the program works.
At one point, the get_arg_info function return value could return either an option character or a status value. I realized that while this was efficient, it was both difficult to read the code, and might not be as flexible in the future, so the function was modified to take a pointer to type TCHAR that is used to return any option character that the parser detects.
The python get_arg_info_creator.py largely just copies very large strings that contain the code. I considered just putting the generated header file and C file in the directory and copying those to each new project. This would not allow updating the date of the file, and it would not allow future changes.
Someday, if I have time, I might simplify the code that generates print statements for C and C++ to be done using a common function, instead of having if-else statements everywhere for every print line. Doing this would also make it easier to add an option for just using "printf" statements for C code and just std::cout for C++ code, instead of wrapping C print calls with "_tprintf", and C++ calls with the macro "STD_OUT" in order to support compiling for either Unicode or ASCII. If someone only wants a basic ASCII build, these wrappers are extraneous.
History
- First posting.
- Updated the help text in the article and in the code. Uploaded the latest code.
- Updated the code to fix a bug when making C++ programs. Fixed other minor bug.
- Fixed header file generation so the generated code compiles on Linux too. Fixed an argument parsing bug.
- Improved the parser code. Added support for Visual Studio 2017. See the README.txt file for how to return support older Visual Studio 2008 build files.
- Refactored generated argument parsing code. Minor cleanup of formatting errors.
- Refactored python code to eliminate some duplication. Fixed generation of "
_T('\0')
" text in get_arg_info.c - Refactored generated C code for the main program to make it simpler.
- Changed
if
-else
construct to a switch
statement in the generated code. - Rewrote code. The previous code uses one variable to return both status and option character values. The code was modified to use two variables, which is much more readable.
- Minor cleanup. Rearranged parsing code again. Software is never done.
- Updated version number and very minor format changes. Added some design decision comments to the article.
- For current version 1.5. I cleaned up the python parser. The tilde (~) argument option was removed, and not all optional arguments start with a dash character. Other than that the first positional argument must specify the file name for the generated main program, the order of arguments no longer matters. It might be worth refactoring nmore parts of the parser into functions, but at this point, the code is already much easier to read. I also fixed the code generation for the display_usage function, so that the text is aligned. The help text was also made clearer. Finally, in the generated code, after display_usage is called, the _exit function is called.
- A header file was missing, so the exit function was not found at compile time. Added the header file and changed the _exit function to exit. I have no compiled on Linux in a while, but it's probably correct. Windows(TM) is correct now.
- Version 1.6 fixes a bug where if there were no required arguments for the generated program, incorrect code was generated.