gawk1.01源碼awk3.c分析

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章