文档章节

GNU M4 笔记

R
 ReJaVu
发布于 2013/12/15 09:14
字数 892
阅读 2792
收藏 8

认识 GNU M4

m4 是个宏处理器,像 C 语言的宏一样,用来替换文本。

在终端上输入 m4 [文件名] ,这时候 m4 读取文件,然后输出结果。 如果不指定文件名,就将标准输入作为指令。

为了方便演示,在代码块里面,没有“=>”的是输入,有“=>”的是输出。现在打开 m4,输入

	hello world
	=>hello world

在这里输出的结果和输入一样。接着我们定义宏 hello,

	define(`hello',`hi')
	=>
	hello world
	=>hi world

可见 hello 已经被替换成 hi 了。define 是 m4 的内置宏,它用来定义一个宏。 这里将 hello 定义成 hi,在输入 hello world 的时候就进行了宏调用。 如果想阻止调用,可以使用引用(quoting):

	define(`hello',`hi')
	=>
	`hello' world
	=>hello world
	``hello'' world
	=>`hello' world

使用一对“`'”将字符引用之后 m4 就不会试图对它进行替换,仅仅看作是字符串。 空的引用“`'”表现出来的是 null string。顾名思义,null string 不包含任何字符。

m4 将 null string、空格、新行和其它一些特殊符号(除了下划线“_”、左括号“(”、“ ` ”字符)之间的词分割成 token。默认地,m4 原封不动地输出字符串(以“`'”括起)、特殊字符和注释,并试图查找该 token 是否是定义过的宏,如果没有定义过就照样输出,否则进行宏展开。所以,

	hello world
	=>hello world <-- “hello”和“world”都没定义过,按原来输出
	define(`hello',`hi') <-- 定义宏 hello
	=>
	hello world
	=>hi world <-- hello 已定义,展开
	helloworld
	=>helloworld <-- helloworld 未定义,按原来输出
	hello`'world
	=>hiworld <-- 空字符串“`'” 类似空格可以分割 token,注意这里两个词之间没空格
	he`'llo
	=>hello <-- he  和 llo 未定义,按原来输出,null string 不占空间
	`hello' world
	=>hello world <-- 引用为字符串,不展开

m4 展开一个宏之后,还会再检查展开后的输出是宏与否,并反复如此:

	define(`hello',`hi')
	=>
	define(`hi',`你好')
	hello world
	=>你好 world

一个死循环 :)

	define(`hello',`this is hello')
	hello world

接着来看 define 这个内置宏,

	define(`hello',`hi')
	=>

在这里调用了 define,紧随其后在括号里用逗号分开是给它的两个参数。第一个参数是宏名,第二个是展开体。 默认地,define 宏输出一个新行,如果想要删除一个新行,可以在 define 后面添加 dnl 宏,dnl 表示 delete new line,也是一个内置宏。

自定义的宏可以使用$1,$2 ... $n 引用参数:

	define(`echo',`$1 $2')
	=>
	echo(para1)
	=>para1 
	echo(para1,para2)
	=>para1 para2

对宏的参数使用引用(quote)可以控制是否展开参数。来看 GNU M4 官方手册上的一个例子:

	define(`active', `ACT, IVE')
	=>
	define(`show', `$1 $1')
	=>
	show(active)
	=>ACT ACT
	show(`active')
	=>ACT, IVE ACT, IVE
	show(``active'')
	=>active active

根据手册上的说法,当宏的参数没有引用一层的时候,在宏展开前先尝试展开参数;引用一层时,在宏展开之后展开参数;引用两层时不展开。

结合上面的例子,

	define(`active', `ACT, IVE')
	=>
	define(`show', `$1 $1')
	=>
	show(active) --> show(ACT,IVE)
	=>ACT ACT
	show(`active') --> active active
	=>ACT, IVE ACT, IVE
	show(``active'') --> `active' `active'
	=>active active

另外我发现,对于 define 宏的第一个参数如果不加引用会:

	define(a,`b')
	=>
	a
	=>b
	define(a,`c')
	=>
	a
	=>c
	b
	=>c

如果加了两层引用我找不到宏名是什么:

	define(``a'',`b')
	=>
	a
	=>a
	`a'
	=>a
	``a''
	=>`a'

所以,define 的第一个参数还是别用两层引用吧。

© 著作权归作者所有

共有 人打赏支持
R
粉丝 2
博文 4
码字总数 3906
作品 0
益阳
程序员
私信 提问
加载中

评论(1)

王洪敏
王洪敏
我来和楼主交流下文章最后一个疑问

define(``a'',`b')
defn(``a'')
即可
详解linux下auto工具制作Makefile源码包(工具安装篇)

详解linux下auto工具制作Makefile源码包(工具安装篇) 水木杨 一、引子 最近学习安装源码包,然后公司开发也需要制作源码包,所以就稍微学习了一下automake与autoconf制作configure以及Mak...

慎道
2011/07/14
0
0
cmake ..这一步就报错,m4,autoconf和automake都安装了啊

make: *** [aclocal.m4] 错误 127 CDPATH="${ZSH_VERSION+.}:" && cd . && /bin/sh /app/bin/QConf/deps/gdbm/build-aux/missing aclocal-1.14 -I m4 /app/bin/QConf/deps/gdbm/build-aux/m......

GreatQing
2015/11/06
2.1K
0
PHP动态编译出现Cannot find autoconf

在安装完PHP后,想动态编译PHP的memcache扩展库 cd memcache-2.2.5/ /usr/local/webserver/php/bin/phpize ./configure --with-php-config=/usr/local/webserver/php/bin/php-config 但是执行......

晨曦之光
2012/03/09
773
0
php为redis创造编译环境出错解决办法

执行/usr/local/webserver/php/bin/phpize时出现错误:Configuring for: PHP Api Version: 20041225 Zend Module Api No: 20060613 Zend Extension Api No: 220060519 Cannot find autoconf.......

山鹰sniper
2014/07/17
0
0
gnu m4 和 m4 有什么区别呢?

gnu m4 和 m4 有什么区别呢?在/usr/bin下有gm4和m4,两个文件大小相同。

RickHuang
2011/08/24
1K
2

没有更多内容

加载失败,请刷新页面

加载更多

大数据教程(8.3)wordcount程序运行过程的解析

上一篇博客分享了wordcount的源码编写、原理实现,本节将对wordcount在hadoop内部运行过程进行解析。 运行流程图如下: 上图中说明:mr appmaster启动后,会根据任务分配规则进行任务的启动,...

em_aaron
24分钟前
1
0
Zookeeper安装(LINUX环境)

一、上传安装包 二、解压安装包 mkdir -p /usr/lib/jvm tar -zxvf zookeeper-3.4.10.tar.gz -C /usr/lib/jvm 三、修改配置文件 复制zoo_sample.cfg改名zoo.cfg 给zoo.cfg赋权 chmod 777 zoo.......

开源中国首席碉堡了
46分钟前
2
0
【面试必问】支撑百万并发的"IO多路复用"技术你了解吗?

多路复用其实并不是什么新技术,它的作用是在一个通讯连接的基础上可以同时进行多个请求响应处理。对于网络通讯来其实不存在这一说法,因为网络层面只负责数据传输;由于上层应用协议的制订问...

Java干货分享
49分钟前
3
0
Rotate Array(leetCode189)

Given an array, rotate the array to the right by k steps, where k is non-negative. Example 1: Input: [1,2,3,4,5,6,7] and k = 3Output: [5,6,7,1,2,3,4]Explanation:rotate 1 s......

woshixin
今天
1
0
给女朋友讲解什么是Optional【JDK 8特性】

前言 只有光头才能变强 前两天带女朋友去图书馆了,随手就给她来了一本《与孩子一起学编程》的书,于是今天就给女朋友讲解一下什么是Optional类。 至于她能不能看懂,那肯定是看不懂的。(学到...

Java3y
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部