u-boot-2009.11.y 根目录kbuild sed-y分析

# Default sed regexp - multiline due to syntax constraints
define sed-y
	"s:[[:space:]]*\.ascii[[:space:]]*\"\(.*\)\":\1:; \
	/^->/{s:->#\(.*\):/* \1 */:; \
	s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
	s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
	s:->::; p;}"
endef

# Use filechk to avoid rebuilds when a header changes, but the resulting file
# does not
define filechk_offsets
	(set -e; \
	 echo "#ifndef $2"; \
	 echo "#define $2"; \
	 echo "/*"; \
	 echo " * DO NOT MODIFY."; \
	 echo " *"; \
	 echo " * This file was generated by Kbuild"; \
	 echo " */"; \
	 echo ""; \
	 sed -ne $(sed-y); \
	 echo ""; \
	 echo "#endif" )
endef

sed-y 在filechk_offsets中调用,是作为sed -ne 的脚本输入,整个脚本分为两部分,

  1. s:[[:space:]]*\.ascii[[:space:]]*\"\(.*\)\":\1:
  2. /^->/{s:->#\(.*\):/* \1 */:; \ s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \ s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \ s:->::; p;}

sed -ne 是将使用脚本处理输入字符串,放在缓冲区,不输出,待接收到p参数,再行输出,
filechk_offsets处理的文件有两个,
以lib/asm-offsets.s 为例

$(obj)/$(generic-offsets-file): lib/asm-offsets.s FORCE
	$(call filechk,offsets,__GENERIC_ASM_OFFSETS_H__)

我们先给出结论,这个脚本就是为了处理类似下列的字符串,

.ascii "->GD_START_ADDR_SP #60 offsetof(struct global_data, start_addr_sp)"	@

第一部分

s:[[:space:]]*\.ascii[[:space:]]*\"\(.*\)\":\1:
[[:space:]]*是0个空格或多个空格
\.ascii 是.ascii 字符串
\" 是双引号字符串
\(.*\)是一个元组,.*代表0个或多个字符
\1 代表第一个元组,在这个规则中,也就是\(.*\)所代表的字符串
整句规则的意思就是,将以0个或多个空格加.ascii "开头到结尾的中间字符串取出,也就是取出这两个开头和结尾
例如

.ascii "->GD_START_ADDR_SP #60 offsetof(struct global_data, start_addr_sp)"	@

会被处理成

->GD_START_ADDR_SP #60 offsetof(struct global_data, start_addr_sp) @

其他不满足这个条件的行,都不会被处理

第二部分

/^->/{s:->#\(.*\):/* \1 */:; \ s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \ s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \ s:->::; p;}

/^->/{ }这个规则是说,过滤字符串,只要满足一->开头的,然后对过滤后的字符串执行{ }中的规则
{ }中一个四个规则
s:->#\(.*\):/* \1 */:->#开头的字符,保留,但是去除->#,并在前后加上/* */
例如

->#TEST

会被替换成

/*TEST*/

s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:
^-> 代表以->开头
\([^ ]*\)代表一个元组,0个或若干个非字符
[\$$#]* 代表以0个或若干个#结尾,这是makefile中的写法,shell中只要[\$#]
\([-0-9]*\) 任意0个或若干个字符串
\(.*\) 任意字符串
#define \1 \2 /* \3 */ 对三个元组进行处理 加上#define开头,对元组三加前后 /* */,其他字符串不动
例如

->GD_START_ADDR_SP #60 offsetof(struct global_data, start_addr_sp) @

会被处理为

#define GD_START_ADDR_SP  /*  #60 offsetof(struct global_data, start_addr_sp) @ */

剩下两个规则不在赘述。

你可能感兴趣的:(u-boot)