coreutils4.5.1 wc.c代码分析

coreutils4.5.1 wc.c代码分析
再读wc.c,看出了一点眉目,有些夸张了,我只是说,对程序的大体框架有些了解,离能修改代码的程度还差得远呢。不过,正因为是新手,所以不妨把步子迈得大些,反正就是练手,不要太多的成见在里面。
先看main()
其中对选项的处理很简单,设置几个全局量,然后分析选项时,再对全局量赋值。逻辑如下:
  while ((optc = getopt_long (argc, argv, "clLmw", longopts, NULL)) != -1)
    switch (optc)
      {
      case 0:
    break;

      case 'c':
    print_bytes = 1;
    break;

      case 'm':
    print_chars = 1;
    break;
原谅我不能复制得太多,不然不如看源代码呢。
作者用到了一个技巧,当没有给任何选项时,是行数,字数,字节数一起显示,如何弄的呢?
  if (print_lines + print_words + print_chars + print_bytes + print_linelength
      == 0)
    print_lines = print_words = print_bytes = 1;
看到没,当没有给任何参数时,就把这三项全部为1,也就是显示行数,单词数,和字节数。哈哈!
下面进入正题,开始计数。
  if (nfiles == 0)
    {
      have_read_stdin = 1;
      wc (0, "");
    }
当有多个文件要wc时,用wc_file函数进行了封装,其实还是调用wc
所以继续进入 wc函数。
这个函数,看得就想吐了。
  if (count_bytes && !count_chars && !print_lines && !count_complicated)
    {
    }
  else if (!count_chars && !count_complicated)
    {
    }
  else if (MB_CUR_MAX > 1)
    {
    }
  else {}
  write_counts (lines, words, chars, bytes, linelength, file);
  total_lines += lines;
  total_words += words;
  total_chars += chars;
  total_bytes += bytes;
      }
看到没,当前文件的统计完了,就打印结果,如果有几个文件,还要把全部文件的加起来。
所以对wc命令的总体执行就基本清楚了。
那究竟如何统计行数、单词数、字节数呢?

 else if (MB_CUR_MAX > 1)
    {
    }
这一段。
     while ((bytes_read = safe_read (fd, buf + prev, BUFFER_SIZE - prev)) > 0)
    {
      const char *p;
# if SUPPORT_OLD_MBRTOWC
      mbstate_t backup_state;
# endif

      bytes += bytes_read;
      p = buf;
其中对字节数的统计,很简单,就是把每次数出来的进行汇总即可。上文中,
  bytes += bytes_read
那如何统计行数呢?
      switch (wide_char)
            {
            case '\n':
              lines++;
              /* Fall through. */
            case '\r':
            case '\f':
              if (linepos > linelength)
            linelength = linepos;
              linepos = 0;
              goto mb_word_separator;
            case '\t':
              linepos += 8 - (linepos % 8);
              goto mb_word_separator;
            case ' ':
              linepos++;
              /* Fall through. */
            case '\v':
            mb_word_separator:
              if (in_word)
            {
              in_word = 0;
              words++;
            }
看到没,当遇到回车时,就把行数累加。关键是如何计算单词数,作者用了一个技巧:
  case '\v':
            mb_word_separator:
              if (in_word)
            {
              in_word = 0;
              words++;
            }
反正大致意思是,如果出现了字母,设为单词开始,再遇到非字母时,表示已经识别了一个单词,words++,如此这样,但代码真没看明白。只是大致知道。
等心情好时,再慢慢看吧。
我把vim字体扩大,这样看得清楚,但每屏显示的代码行数就少了。也许我要把屏幕横着放,这样每屏显示的行数多些。这么多的if,看得头晕了。
我要睡觉了,等清醒时,再看吧。
 

猜你喜欢

转载自blog.csdn.net/woshiyilitongdouzi/article/details/85779515
今日推荐