除了autoconf之外,m4还有值得注意的用途吗? [关闭]

问题描述 投票:8回答:9

有人知道m4除了autoconf之外的任何用途(最好是在ac或c ++环境中),这不仅仅是学术上的优秀,因为它有助于解决一个问题,否则(例如使用'标准'预处理器)很难解决。

我问这个是因为我正在考虑用c ++做一个项目的方法,我希望通过使用脚本,预处理器,whatevers来减少或减少冗余。

c++ c preprocessor autoconf m4
9个回答
5
投票

我曾经使用m4从包含简单版本字符串(MAJOR.MINOR.MICRO-STATUS)的文本文件生成C ++头文件,并从Windows Visual Studio项目生成来自subversion的信息。

m4是我可以轻松嵌入并用于此特定目标的最小宏引擎。

它看起来像这样:

#ifndef __VERSION_H__
#define __VERSION_H__
divert(-1)
define(`CPP_DEFINE', `#define $1 $2')
define(`VERSION', include(`version.txt'))
define(`MY_SOFTWARE_MAJOR', regexp(VERSION, `\([0-9]+\)\.[0-9]+\.[0-9]+', `\1'))
define(`MY_SOFTWARE_MINOR', regexp(VERSION, `[0-9]+\.\([0-9]\)+\.[0-9]+', `\1'))
define(`MY_SOFTWARE_MICRO', regexp(VERSION, `[0-9]+\.[0-9]+\.\([0-9]\)+', `\1'))
define(`MY_SOFTWARE_STATUS', regexp(VERSION, `\(-\w+\)', `\1'))
define(`SVN_REV', `regexp(esyscmd(svnversion -n), `[0-9]+', `\&')')
ifelse(len(SVN_REV), 0, `define(`NO_SVN')')
divert
CPP_DEFINE(MY_SOFTWARE_VERSION, format(`"%s.%s.%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO))
CPP_DEFINE(PRODUCT_VERSION, format(`"%s.%s.%s%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO, MY_SOFTWARE_STATUS))
CPP_DEFINE(COPYRIGHT_NOTICE, `"Copyright (C) 2008 - Me"')
ifdef(`NO_SVN', `
CPP_DEFINE(ABOUT_VERSION, format(`"My Software Version %s.%s.%s%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO, MY_SOFTWARE_STATUS))
CPP_DEFINE(FILE_VERSION, format(`"%s.%s.%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO))
CPP_DEFINE(INFO_VERSION, format(``%s,%s,%s,0'', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO))
', `
CPP_DEFINE(ABOUT_VERSION, format(`"My Software Version %s.%s.%s.%s%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO, SVN_REV, MY_SOFTWARE_STATUS))
CPP_DEFINE(FILE_VERSION, format(`"%s.%s.%s.%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO, SVN_REV))
CPP_DEFINE(INFO_VERSION, format(``%s,%s,%s,%s'', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO, SVN_REV))
')
#endif /* __VERSION_H__ */

虽然它工作得很好,但这实际上是我没有重申的实验,主要是因为我现在更喜欢使用CMake的内置功能来直接处理这些东西并生成我的Visual Studio项目文件。


5
投票

GNU Bison在内部使用它来生成C或C ++解析器文件。


3
投票

我使用过m4并且对它的功能印象深刻,这就是C预处理器应该是什么。我用它从简单的项目描述生成GNU makefile。


3
投票

Sendmail提供基于M4的基础架构,用于生成配置文件。我使用过的大多数sendmail安装都提供了这个配置sendmail的推荐方法。


3
投票

我用m4生成包含struct声明列表的C / C ++文件。根据结构的丑陋程度,如果你做得对,m4文件比C / C ++文件更容易阅读和编辑。


3
投票

我曾经用它来生成一些恶魔SQL查询。印刷,查询大约20页 - 大约1200行,我想。我很确定没有m4我就做不到,而且我很感激我不会再这样做了。


(Responding to a comment . . .)

IIRC(从30年前开始),该查询推动了原告的报告。原告按其历史事件的组合进行分类。

SQL引擎无法在视图上构建视图,并且不支持用户定义的函数。派生表,子选择等的一些长表达式

  • 应该是相同的,但不是,或
  • 应该是微妙的不同(需要' - '而不是'+',或'shsapnm'而不是'shsgpnm'),但是以错误的方式不同。

困难的部分不是编程。

第一个困难的部分是弄清楚哪三个略有不同的子选择是正确的,或者我们是否真的需要三个不同的子选择,或者我们是否真的需要现有的三个加一个或两个。 (我认为答案最终证明是“以上所有”。)相关报告需要一些相同的子选择; m4 +保证他们是一样的。

第二个难点是构建测试数据,可以显示查询在所有各种复杂的原告历史中正常运行。我认为Joe Celko引导我走向波音当时正在使用的一些商业软件 - 它采用了一些用户定义的标准,并为每种可能的组合或排列生成了测试工具和存根。我不记得它的名字。 (我想是这样的:Logic Gem


1
投票

用于GTK +的官方C ++绑定库,gtkmm - 一个优秀的项目,通过更加现代的C ++使GTK + GUI的功能和范围可访问 - 使用m4作为其工具集的一部分,可以轻松生成包装代码。

(我与任何G *项目都没有任何关系。我非常喜欢gtkmm,觉得它不是那么有名,特别是对某些明显的选择。而且,我不知道m4是K&R,直到我研究为此!整洁。)


0
投票

我使用M4自动生成DDL脚本来定义您的SQL表,C ++代码和标题来访问它们,以及测试它的驱动程序。我认为我们还更新了脚本以同时备份和重新填充表格,但是自从我这样做以来已经有15年多了。


0
投票

我使用cpp和m4来替换文件中的标记,并为不同的目标平台生成打包文件。现在我将使用ruby erb来做到这一点。而在太阳时我使用m4预处理头文件

© www.soinside.com 2019 - 2024. All rights reserved.