gawk1.01源码awk3.c分析
我一边读源码,一边把自己的一些想法写出来。我的笔记本外接了一个显示器。
init_vars()
这个过程,对FS,NF,RS,NF,FILENAME,OFS,ORS,OFMT几个变量进行初始化。
其过程很有意思,
FS_node=spc_var("FS",make_string(" ",1));
spc_var("FS",make_string("
",1))就对变量进行了赋值。当FS在数据库中不存在,就插入之,如果存在,就更新。类似数据库操作merge
get_ofmt()
get_fs()
set_fs()
其中get_lhs(FS_node)是取得FS_node的指针,而不纯粹是get,实际上,有set的功能在里面。我当时迷惑了很久。我说,你不是get吗,怎么还能修改呢?
set_fs(str)
char *str;
{
register NODE **tmp;
tmp= get_lhs(FS_node);
do_deref();
/* stupid special case so -F\t works as documented in awk */
/* even though the shell hands us -Ft. Bleah! (jfw) */
if (*str == 't') *str == '\t';
*tmp=make_string(str,1);
}
大家看源码,tmp是指针,修改*tmp就是修FS_node,玄吧。
其中do_split比较有意思。
象split("11/01/1990",a,"/")操作后
a[1]=11
a[2]=01
a[3]=1990
作者是用assoc_lookup函数,查看a数组有没有?此处没细看。有几个assoc打头的函数不知什么意思。
hack_print_node(tree)
NODE *tree;
{
register FILE *fp;
#ifndef FAST
if(!tree || tree->type != Node_K_print)
abort();
#endif
fp=deal_redirect(tree->rnode);
tree=tree->lnode;
if(!tree) tree=WHOLELINE;
if(tree->type!=Node_expression_list) {
print_simple(tree,fp);
} else {
while(tree) {
print_simple(tree_eval(tree->lnode),fp);
tree=tree->rnode;
if(tree) print_simple(OFS_node->var_value,fp);
}
}
print_simple(ORS_node->var_value,fp);
}
这个打印函数很有意思。如果能有实际数据演练一下,就好啦。
get_two(tree,res1,res2)
NODE *tree,**res1,**res2;
{
if(!tree) {
*res1= WHOLELINE;
return;
}
#ifndef FAST
if(tree->type!=Node_expression_list)
abort();
#endif
*res1=tree_eval(tree->lnode);
if(!tree->rnode)
return;
tree=tree->rnode;
#ifndef FAST
if(tree->type!=Node_expression_list)
abort();
#endif
*res2=tree_eval(tree->lnode);
}
其中res1,res2都是取的lnode。原来rnode就是指向下一链表的指针。这个很有意思。
我还是想把语法树画出来。
inrec()
函数在awk1.c中有用到。主要功能就是从文件中读取一行。并拆分成字段,存储到$0,$1...中去。
先读一行。
存储这一行到$0中去。
给变量NR+=1
对当前行循环处理
当找到字段分隔符后,就存入$i中。i+=1
把最后一个字段存储到$i中。
大致这是样,但其中拆分字段的部分,还不很清楚。