文章目录
- 1. 目的
- 2. 原始代码
- 3. 化简和跨平台支持
- 4. 修改后代码的代码分析
- 5. References
1. 目的
阅读 netbsd 9.3 的 echo.c
, 练习 C 语言源码阅读的技能。
2. 原始代码
https://github.com/NetBSD/src/blob/trunk/bin/echo/echo.c
/* $NetBSD: echo.c,v 1.23 2021/11/16 21:38:29 rillig Exp $ *//** Copyright (c) 1989, 1993* The Regents of the University of California. All rights reserved.** Redistribution and use in source and binary forms, with or without* modification, are permitted provided that the following conditions* are met:* 1. Redistributions of source code must retain the above copyright* notice, this list of conditions and the following disclaimer.* 2. Redistributions in binary form must reproduce the above copyright* notice, this list of conditions and the following disclaimer in the* documentation and/or other materials provided with the distribution.* 3. Neither the name of the University nor the names of its contributors* may be used to endorse or promote products derived from this software* without specific prior written permission.** THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF* SUCH DAMAGE.*/#include <sys/cdefs.h>
__COPYRIGHT(
"@(#) Copyright (c) 1989, 1993\The Regents of the University of California. All rights reserved.");#if 0
static char sccsid[] = "@(#)echo.c 8.1 (Berkeley) 5/31/93";
#else
__RCSID("$NetBSD: echo.c,v 1.23 2021/11/16 21:38:29 rillig Exp $");
#endif#include <err.h>
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>/* ARGSUSED */
int
main(int argc, char *argv[])
{bool nflag;setprogname(argv[0]);(void)setlocale(LC_ALL, "");/* This utility may NOT do getopt(3) option parsing. */nflag = *++argv != NULL && strcmp(*argv, "-n") == 0;if (nflag)++argv;while (*argv != NULL) {(void)printf("%s", *argv);if (*++argv != NULL)(void)putchar(' ');}if (!nflag)(void)putchar('\n');(void)fflush(stdout);if (ferror(stdout) != 0)err(1, "write error");return 0;
}
3. 化简和跨平台支持
删除头部版权信息的文本。
err.h
在 MSVC 编译器下不存在,err()
改为 fprintf()
.
使用 clang-format 修改了编码风格:
BasedOnStyle: Microsoft
IndentWidth: 4
修改后的完整代码:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char *argv[])
{bool nflag;// detect "-n" optionnflag = *++argv != NULL && strcmp(*argv, "-n") == 0;if (nflag)++argv;while (*argv != NULL){printf("%s", *argv);if (*++argv != NULL){putchar(' ');}}if (!nflag){putchar('\n');}fflush(stdout);if (ferror(stdout) != 0){fprintf(stderr, "write error");}return 0;
}
4. 修改后代码的代码分析
检查是否传入了 -n
参数:
其中 *++argv
表示, 先让 argv = argv + 1
, 再取*argv
.
原样输出每个输入的字符: 如果不是最后一个字符, 则跟随输出一个空格:
如果输入了 -n
选项, 那么主动输出一个换行符:
刷新io的缓冲区,立即输出到屏幕上。如果输出出现了错误,输出到标准错误输出上:
5. References
- Cannot open source file err.h in visual studio?