C 或 C++ 控制台程序代码生成器






4.80/5 (10投票s)
以下程序是一个代码生成器,用于生成具有自动生成解析代码的 C 或 C++ 程序。
引言
此程序生成 C 或 C++ 程序,这些程序可以解析命令行参数并显示已解析的值。此程序旨在节省打字时间,并允许快速创建可用于特定目的的程序。
该程序旨在节省编写 C 或 C++ 控制台程序时的打字时间。虽然程序生成的代码可以运行,但预计用户会想要修改生成的代码。
将创建一个与命令行中传入的程序名称的基本名称同名的文件夹,并在该文件夹中创建生成的代码。
更新:2019 年 2 月 11 日
新的上传现在生成 Visual Studio 17(和 15?)的生成文件。
以前的文件 get_arguments_function_creator.py 被 get_arg_info_creator.py 取代。新代码生成了一个解析器,该解析器允许在行中组合布尔选项,即,在生成的 C 或 C++ 程序中,用户不必在命令行中输入“-a -b -c
”,而是可以使用参数“-abc
”。
该代码还具有更多功能,可以通过键入以下内容访问帮助来查看:
python make_c_cpp_prog.py -h
背景
该程序是用 Python 2.7 版本编写的,但它也应该可以在 Python 2.6 中运行。该程序由以下文件组成:
make_c_cpp_prog.py | 主程序文件,用于解析输入参数并调用其他 Python 文件来创建生成的文件。 |
c_cpp_program_creator.py | 主要的**代码生成器**,它创建 C 或 C++ 代码的主文件,该文件解析并显示参数。 |
carginfo.py | 存储生成程序参数的类型、名称和默认值信息。 |
program_properties.py | 存储是生成 C 还是 C++ 程序以及其他程序属性。 |
cpp_keyword_checker.py | 识别名称是否为 C++ 关键字。即使正在生成 C 代码,最新的 C++ 11 关键字也会被禁止。 |
makefile_creator.py | 创建 Linux Makefile。 |
get_arg_info_creator.py | 创建文件 get_arg_info.c 和 get_arg_info.h,它们用于解析 C 或 C++ 参数。 |
platform_os_creator.py | 创建头文件 platform_os.h,它用于定义平台和操作系统特定的符号。 |
vs_build_creator.py | 创建 Visual Studio 生成文件。 |
example_program.bat | 这不是程序的一部分。此 Windows TM 批处理文件运行该程序以生成示例程序。用户必须在批处理文件名后提供一个文件名。 |
我最近一直在 Windows 上使用 Visual Studio 进行编译。Linux 以前也能工作,虽然我不认为会有问题,但 platform_os.h 文件和 Makefile 可能需要一些调整才能在 Linux 上使用。如果出现任何问题,我会更新代码。
Using the Code
用法
python make_c_cpp_prog.py <program name> <parameter arguments>
版本 1.5
此程序创建一个 C 或 C++ 命令行程序,具有可选参数解析功能,并为 Windows(TM) 和 Linux 创建程序生成文件。
程序命令行形式如下:
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]
形式 <x>
表示 x
是必需的,而形式 [y]
表示 y
是可选的。
程序名称
<program_name>
参数以文件扩展名“.c”(表示 C 程序)结尾,或者以“.cpp”或“.cc”(表示 C++ 程序)结尾。
参数参数
每个生成程序的参数参数都是一个逗号分隔的列表,形式为:
<var_name[="initial_value"]>[,var_type][,-short_switch][,--long_switch]
变量名必须在前。var_type
和 switch
参数可以按任何顺序排列。
参数参数 - 关于 var_name
变量名必须是每个参数指定的第一个项。变量名只能包含英文字母、数字或下划线字符。变量名的第一个字母不能是数字字符。
可选参数可以指定默认值。要定义默认值,请在变量名后跟一个等号和默认值。对于 string
,如果默认值包含空格,则默认值必须用双引号括起来。
布尔参数的唯一有效值为:false和 true
。
对于 C 程序,这些将被更改为“FALSE
”和“TRUE
”。
参数参数 - 关于 var_type
var_type
说明符可以是以下字符之一。
如果未为这些类型中的每种类型指定 initial_value
,则使用指定的初始默认值。
s
-string
参数。string
默认为空string
。i
- 整数参数。默认值为0
。f
- 浮点数参数。默认值为0.0F
。d
- 双精度浮点数参数。默认值为0.0
。b
- 布尔参数。默认值为FALSE
。
如果未指定 var_type
,则 var_type
默认为 's
',表示 string
参数。
参数参数 - 切换
初始连字符表示一个 switch
。单个连字符表示一个短的、单字符的 switch
名称。
两个初始连字符指定一个长名称 switch
。
短名称 switch
和长名称 switch
都可以指定。
“-h
”和“--help
”开关会自动实现,不应将其指定为 switch
参数。
参数参数 - 关于布尔参数
布尔参数(var_type
为 'b
')通常用作可选的 switch
参数。在生成的程序中使用 switch
来处理布尔参数会导致布尔参数的变量名设置为与 initial_value
相反的值。
代码生成控制选项
以下 Python 程序选项控制生成文件的编译器和链接器设置。目前,这些选项仅影响生成的 Windows(TM) Visual Studio 15 项目文件。
控制布尔选项的开关的短形式可以组合,因此“-u -s
”可以替换为“-us
”。(在生成的 C 或 C++ 代码中,布尔选项的短形式也可以组合)。
-u
| --unicode
- 指定使用 Unicode 字符。
默认使用 ASCII。
-s
| --static
- 指定使用静态系统运行时库。
默认使用动态链接库(DLL)。
-h
| --help
- 打印此帮助文本并退出。
命令行示例
python make_c_cpp_prog.py foo.cpp -us alpha,i beta,f file_name gamma,-g,--gm,b
此命令行生成一个名为“foo.cpp" 的程序。
第一个参数指定使用 Unicode 字符进行构建,并指定链接到 static
运行时库。生成的程序接受一个名为“alpha
”的整数参数,一个名为“beta
”的浮点数参数,一个名为“file_name
”的 string
参数,最后是一个可选参数“gamma
”,它是一个布尔值,只有当在生成的程序的命令行中指定了 '-g
' 开关或 '--gm
' 开关时才为“true
”。
python make_c_cpp_prog.py foo file_name the_name="abc",-n,--name
此命令行创建一个名为“foo.c" 的程序,该程序接受一个名为“file_name
”的单个可选参数和一个名为“the_name
”的可选参数。如果命令行中未指定可选参数,则变量“the_name
”将默认为值“abc
”。
创建的文件
<program name>.c | 对于 C++,文件扩展名将是“.cc”或“.cpp” |
platform_os.h | 包含平台和操作系统特定定义的头文件 |
get_arg_info.h | 'get_arg_info ' 函数的头文件 |
get_arg_info.c | 'get_arg_info ' 函数的实现文件 |
<base program name>.sln | Visual Studio 2015 解决方案文件 |
<base program name>.vcxproj | Visual Studio 2015 项目文件 |
<base program name>.vcxproj.filters | Visual Studio 2015 项目过滤器文件 |
Makefile | Linux Makefile |
此处无法列出生成的单个程序文件的内容。
关注点
此代码是随着时间的推移而演变的。如果我重写它,我可能会以不同的方式编写,但程序是有效的。
曾经,get_arg_info 函数的返回值可以是选项字符或状态值。我意识到虽然这很高效,但代码很难读,而且将来可能不够灵活,因此修改了该函数,使其接受一个 TCHAR 类型指针,用于返回解析器检测到的任何选项字符。
Python 文件 get_arg_info_creator.py 大部分只是复制包含代码的大字符串。我曾考虑将生成的头文件和 C 文件直接放在目录中,然后将它们复制到每个新项目中。这样就无法更新文件的日期,也无法进行未来的更改。
将来,如果我有时间,我可能会简化为 C 和 C++ 生成打印语句的代码,使其通过一个公共函数完成,而不是在每个打印行上都有 if-else 语句。这样做还可以更容易地添加一个选项,只为 C 代码使用“printf”语句,只为 C++ 代码使用 std::cout,而不是用“_tprintf”包装 C 打印调用,用宏“STD_OUT”包装 C++ 调用,以便支持 Unicode 或 ASCII 的编译。如果有人只需要基本的 ASCII 构建,这些包装器就是多余的。
历史
- 首次发布。
- 更新了文章和代码中的帮助文本。上传了最新代码。
- 更新了代码以修复创建 C++ 程序时的错误。修复了其他小错误。
- 修复了头文件生成,以便生成的代码也能在 Linux 上编译。修复了一个参数解析错误。
- 改进了解析器代码。增加了对 Visual Studio 2017 的支持。有关如何支持旧版 Visual Studio 2008 生成文件的信息,请参阅 README.txt 文件。
- 重构了生成的参数解析代码。格式化错误得到少量清理。
- 重构了 Python 代码以消除一些重复。修复了 get_arg_info.c 中“
_T('\0')
”文本的生成。 - 重构了主程序的生成 C 代码,使其更简单。
- 在生成的代码中将
if
-else
结构更改为switch
语句。 - 重写了代码。之前的代码使用一个变量来返回状态和选项字符值。代码已修改为使用两个变量,这更易于阅读。
- 少量清理。再次重新排列了解析代码。软件永无止境。
- 更新了版本号和非常小的格式更改。在文章中添加了一些设计决策注释。
- 对于当前版本 1.5,我清理了 Python 解析器。删除了波浪号 (~) 参数选项,并非所有可选参数都以破折号开头。除此之外,第一个位置参数必须指定生成的主程序的文件名,参数的顺序不再重要。也许可以将解析器的更多部分重构为函数,但此时代码已经更容易阅读了。我还修复了 display_usage 函数的生成代码,以便文本对齐。帮助文本也更加清晰。最后,在生成的代码中,调用 display_usage 后,会调用 _exit 函数。
- 缺少一个头文件,因此在编译时找不到 exit 函数。添加了头文件并将 _exit 函数更改为 exit。我已经有一段时间没有在 Linux 上编译过了,但它可能是正确的。Windows(TM) 现在是正确的。
- 版本 1.6 修复了生成程序没有必需参数时生成错误代码的错误。