gawk1.01源码awk3.c分析

本文深入解析gawk1.01版本的源码,重点分析了awk3.c文件中的关键函数如init_vars(), set_fs(), hack_print_node()等的工作原理,探讨了变量初始化、字段拆分及打印功能的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值