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中。
大致這是樣,但其中拆分字段的部分,還不很清楚。