GNU hello代码分析
来源:互联网 发布:网络漂亮的小女孩图片 编辑:程序博客网 时间:2024/05/16 11:14
GNU中的一个软件包,包名叫hello,呵呵,看来很简单啦。
#include "system.h"
#include "errno.h"
#include "error.h"
#include "progname.h"
#include "xalloc.h"
static const struct option longopts[] = {
{"greeting", required_argument, NULL, 'g'}, 需要参数
{"help", no_argument, NULL, 'h'}, 不需要参数
{"traditional", no_argument, NULL, 't'},
{"version", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0} 通过man getopt_long发现,这个结构体需要以NULL结束。
};
/* Forward declarations. */ 前向声明,估计调用在实现之前。
static void print_help (void);
static void print_version (void);
int
main (int argc, char *argv[]) 关键的入口函数在这里啦。
{
int optc;
int lose = 0;
const char *greeting_msg;
wchar_t *mb_greeting;
size_t len;
set_program_name (argv[0]);
/* Set locale via LC_ALL. */
setlocale (LC_ALL, "");
#if ENABLE_NLS
/* Set the text message domain. */
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
#endif
/* Having initialized gettext, get the default message. */
greeting_msg = _("Hello, world!"); 常指针指向一个字符串常量,C语言中有_()这个用法吗?难道是GNU的扩展???
/* Even exiting has subtleties. On exit, if any writes failed, change
the exit status. The /dev/full device on GNU/Linux can be used for
testing; for instance, hello >/dev/full should exit unsuccessfully.
This is implemented in the Gnulib module "closeout". */
atexit (close_stdout);
这个函数用于处理命令行参数,字符后面跟一个冒号表示需要一个参数。
该函数返回短命令符,下面的程序通过case判断。
while ((optc = getopt_long (argc, argv, "g:htv", longopts, NULL)) != -1)
switch (optc)
{
/* --help and --version exit immediately, per GNU coding standards. */
case 'v':
print_version ();
exit (EXIT_SUCCESS);
break;
case 'g':
greeting_msg = optarg; // extern char *optarg;一个全局变量,getopt用它来保存参数
break;
case 'h':
print_help ();
exit (EXIT_SUCCESS);
break;
case 't':
greeting_msg = _("hello, world");
break;
default:
lose = 1;
break;
}
if (lose || optind < argc)
{
/* Print error message and exit. */
error (0, 0, "%s: %s", _("extra operand"), argv[optind]);
print_help ();
}
len = mbsrtowcs(NULL, &greeting_msg, 0, NULL);
if (len == (size_t)-1)
error (EXIT_FAILURE, errno, _("conversion to a multibyte string failed"));
mb_greeting = xmalloc((len + 1) * sizeof(wchar_t));
mbsrtowcs(mb_greeting, &greeting_msg, len + 1, NULL);
/* Print greeting message and exit. */
wprintf (L"%ls\n", mb_greeting);
free(mb_greeting);
exit (EXIT_SUCCESS);
}
/* Print help info. This long message is split into
several pieces to help translators be able to align different
blocks and identify the various pieces. */
static void
print_help (void)
{
/* TRANSLATORS: --help output 1 (synopsis)
no-wrap */
printf (_("\
Usage: %s [OPTION]...\n"), program_name);
/* TRANSLATORS: --help output 2 (brief description)
no-wrap */
fputs (_("\
Print a friendly, customizable greeting.\n"), stdout);
puts ("");
/* TRANSLATORS: --help output 3: options 1/2
no-wrap */
fputs (_("\
-h, --help display this help and exit\n\
-v, --version display version information and exit\n"), stdout);
puts ("");
/* TRANSLATORS: --help output 4: options 2/2
no-wrap */
fputs (_("\
-t, --traditional use traditional greeting\n\
-g, --greeting=TEXT use TEXT as the greeting message\n"), stdout);
printf ("\n");
/* TRANSLATORS: --help output 5+ (reports)
TRANSLATORS: the placeholder indicates the bug-reporting address
for this application. Please add _another line_ with the
address for translation bugs.
no-wrap */
printf (_("\
Report bugs to: %s\n"), PACKAGE_BUGREPORT);
#ifdef PACKAGE_PACKAGER_BUG_REPORTS
printf (_("Report %s bugs to: %s\n"), PACKAGE_PACKAGER,
PACKAGE_PACKAGER_BUG_REPORTS);
#endif
#ifdef PACKAGE_URL
printf (_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
#else
printf (_("%s home page: <http://www.gnu.org/software/%s/>\n"),
PACKAGE_NAME, PACKAGE);
#endif
fputs (_("General help using GNU software: <http://www.gnu.org/gethelp/>\n"),
stdout);
}
/* Print version and copyright information. */
static void
print_version (void)
{
printf ("%s (%s) %s\n", PACKAGE, PACKAGE_NAME, VERSION);
/* xgettext: no-wrap */
puts ("");
/* It is important to separate the year from the rest of the message,
as done here, to avoid having to retranslate the message when a new
year comes around. */
printf (_("\
Copyright (C) %d Free Software Foundation, Inc.\n\
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
This is free software: you are free to change and redistribute it.\n\
There is NO WARRANTY, to the extent permitted by law.\n"), COPYRIGHT_YEAR);
}
今天就来分析一下,GNU的目的是通过这个说明一下,GNU标准软件包所应遵守的规则,以及一些必须的测试,编译脚本文件等。
俺就不分析其他的了,直接上最具价值的代码,其他忽略,这个程序实在是太小了,最重要的是一个getopt_long函数的应用,
用于解析命令行参数的。
#include "system.h"
#include "errno.h"
#include "error.h"
#include "progname.h"
#include "xalloc.h"
static const struct option longopts[] = {
{"greeting", required_argument, NULL, 'g'}, 需要参数
{"help", no_argument, NULL, 'h'}, 不需要参数
{"traditional", no_argument, NULL, 't'},
{"version", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0} 通过man getopt_long发现,这个结构体需要以NULL结束。
};
/* Forward declarations. */ 前向声明,估计调用在实现之前。
static void print_help (void);
static void print_version (void);
int
main (int argc, char *argv[]) 关键的入口函数在这里啦。
{
int optc;
int lose = 0;
const char *greeting_msg;
wchar_t *mb_greeting;
size_t len;
set_program_name (argv[0]);
/* Set locale via LC_ALL. */
setlocale (LC_ALL, "");
#if ENABLE_NLS
/* Set the text message domain. */
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
#endif
/* Having initialized gettext, get the default message. */
greeting_msg = _("Hello, world!"); 常指针指向一个字符串常量,C语言中有_()这个用法吗?难道是GNU的扩展???
/* Even exiting has subtleties. On exit, if any writes failed, change
the exit status. The /dev/full device on GNU/Linux can be used for
testing; for instance, hello >/dev/full should exit unsuccessfully.
This is implemented in the Gnulib module "closeout". */
atexit (close_stdout);
这个函数用于处理命令行参数,字符后面跟一个冒号表示需要一个参数。
该函数返回短命令符,下面的程序通过case判断。
while ((optc = getopt_long (argc, argv, "g:htv", longopts, NULL)) != -1)
switch (optc)
{
/* --help and --version exit immediately, per GNU coding standards. */
case 'v':
print_version ();
exit (EXIT_SUCCESS);
break;
case 'g':
greeting_msg = optarg; // extern char *optarg;一个全局变量,getopt用它来保存参数
break;
case 'h':
print_help ();
exit (EXIT_SUCCESS);
break;
case 't':
greeting_msg = _("hello, world");
break;
default:
lose = 1;
break;
}
if (lose || optind < argc)
{
/* Print error message and exit. */
error (0, 0, "%s: %s", _("extra operand"), argv[optind]);
print_help ();
}
len = mbsrtowcs(NULL, &greeting_msg, 0, NULL);
if (len == (size_t)-1)
error (EXIT_FAILURE, errno, _("conversion to a multibyte string failed"));
mb_greeting = xmalloc((len + 1) * sizeof(wchar_t));
mbsrtowcs(mb_greeting, &greeting_msg, len + 1, NULL);
/* Print greeting message and exit. */
wprintf (L"%ls\n", mb_greeting);
free(mb_greeting);
exit (EXIT_SUCCESS);
}
/* Print help info. This long message is split into
several pieces to help translators be able to align different
blocks and identify the various pieces. */
static void
print_help (void)
{
/* TRANSLATORS: --help output 1 (synopsis)
no-wrap */
printf (_("\
Usage: %s [OPTION]...\n"), program_name);
/* TRANSLATORS: --help output 2 (brief description)
no-wrap */
fputs (_("\
Print a friendly, customizable greeting.\n"), stdout);
puts ("");
/* TRANSLATORS: --help output 3: options 1/2
no-wrap */
fputs (_("\
-h, --help display this help and exit\n\
-v, --version display version information and exit\n"), stdout);
puts ("");
/* TRANSLATORS: --help output 4: options 2/2
no-wrap */
fputs (_("\
-t, --traditional use traditional greeting\n\
-g, --greeting=TEXT use TEXT as the greeting message\n"), stdout);
printf ("\n");
/* TRANSLATORS: --help output 5+ (reports)
TRANSLATORS: the placeholder indicates the bug-reporting address
for this application. Please add _another line_ with the
address for translation bugs.
no-wrap */
printf (_("\
Report bugs to: %s\n"), PACKAGE_BUGREPORT);
#ifdef PACKAGE_PACKAGER_BUG_REPORTS
printf (_("Report %s bugs to: %s\n"), PACKAGE_PACKAGER,
PACKAGE_PACKAGER_BUG_REPORTS);
#endif
#ifdef PACKAGE_URL
printf (_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
#else
printf (_("%s home page: <http://www.gnu.org/software/%s/>\n"),
PACKAGE_NAME, PACKAGE);
#endif
fputs (_("General help using GNU software: <http://www.gnu.org/gethelp/>\n"),
stdout);
}
/* Print version and copyright information. */
static void
print_version (void)
{
printf ("%s (%s) %s\n", PACKAGE, PACKAGE_NAME, VERSION);
/* xgettext: no-wrap */
puts ("");
/* It is important to separate the year from the rest of the message,
as done here, to avoid having to retranslate the message when a new
year comes around. */
printf (_("\
Copyright (C) %d Free Software Foundation, Inc.\n\
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>\n\
This is free software: you are free to change and redistribute it.\n\
There is NO WARRANTY, to the extent permitted by law.\n"), COPYRIGHT_YEAR);
}
0 0
- GNU hello代码分析
- GNU Hello~
- GNU HELLO WORLD
- Pidgin插件Hello world的代码分析
- Android 中间件,hello-jni dame 代码分析
- cocos2d-js中Hello World代码分析
- 分析tensorflow代码(Hello world)
- GNU __attribute__分析
- iPhone开发入门篇 “Hello World”分析代码
- iPhone开发入门篇 “Hello World”分析代码
- GNU Global 代码索引工具
- GNU hello学习笔记(1)——autoconf和automake
- GNU hello学习笔记(1)——autoconf和automake
- php\ajax Hello代码
- 01:Hello, World!【代码】
- Hello, taocp.---踏实&&分析
- 基于x86的Hello World汇编代码分析(AT&T风格汇编)
- V8 学习手册(二)—— hello V8 代码分析与对象添加
- 网上销售平台--数据库物理模型及数据库设计(三)
- Loadrunner11测试ajax接口
- POJ 2184 - Cow Exhibition
- hdu1348 练习凸包模板使用
- iOS tableView的分割线短一节
- GNU hello代码分析
- commons-lang包中我们常用的类
- 01 (maven+SSH)网上商城项目实战之项目简介
- oracle 11g 审计
- D3D11天空盒的实现
- http协议
- 类似aaa?a=1&b=2&c=3&d=4,如何将问号以后的数据变为键值对
- 01 (maven+SSH)网上商城项目实战之项目简介
- 从头到尾写SQL(一)