gnu coreutils-4.5.1 wc.c代码分析


关了手机,定好机械闹钟,一心就把上午读的几个代码写写心得。
wc 这个命令用得很熟悉了,看《flex and bison》中编写一个wc是很简单的,但打开看,wc.c命令也有几百行,596行。
从main开始说起,我读代码是从头到尾看,我总想全部翻一次,再慢慢从尾到头分析。main中,根据传入文件的多少,如果传入多个文件,再打印一个合计信息。
我验证了一下,果然如此。
     for (; optind < argc; ++optind)
 wc_file (argv[optind]);
      if (nfiles > 1)
 write_counts (total_lines, total_words, total_chars, total_bytes,
        max_line_length, _("total"));
其实我难的方法就是再加一句打印语句,读程序时,若找不清头绪,我就根据自己的大致推测,加打印语句。
 所以干活的主要是wc_file这个函数。
wc_file调用wc来解决问题
   wc (fd, file);
再看wc
程序用几个变量来累计计算的结果
  lines = words = chars = bytes = linelength = 0;
主要的结构是一个大的if语句。
 if (count_bytes && !count_chars && !print_lines && !count_complicated)
 {
 }
 else if (!count_chars && !count_complicated)
    {
 
    }
其中还有宏的一段,不管了,其实开头是有注释的,
  /* When counting only bytes, save some line- and word-counting
     overhead.  If FD is a `regular' Unix file, using lseek is enough
     to get its `size' in bytes.  Otherwise, read blocks of BUFFER_SIZE
     bytes at a time until EOF.  Note that the `size' (number of bytes)
     that wc reports is smaller than stats.st_size when the file is not
     positioned at its beginning.  That's why the lseek calls below are
     necessary.  For example the command
     `(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group'
     should make wc report `0' bytes.  */
  /* Use a separate loop when counting only lines or lines and bytes --
  but not chars or words.  */
这段注释我看,大致就是计算行数的处理在此。于是就加打印语句,看它是否走到这儿,执行时,果然走到这里。
  else if (!count_chars && !count_complicated)
    {
      /* Use a separate loop when counting only lines or lines and bytes --
  but not chars or words.  */
      while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0)
 {
   register char *p = buf;
   while ((p = memchr (p, '\n', (buf + bytes_read) - p)))
     {
       ++p;
       ++lines;
     }
   bytes += bytes_read;
 }
      if (bytes_read < 0)
 {
   error (0, errno, "%s", file);
   exit_status = 1;
 }
从代码看,就是看有几个\n,就认为有几行。用的memchr库函数没用过,我在想,争对一些特殊情况,这段代码是正确的吗?后来就想,如果仔细调的话,不划算,先留点尾巴。以后典再看吧。

猜你喜欢

转载自blog.csdn.net/woshiyilitongdouzi/article/details/80401243