博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GNU hello代码分析
阅读量:4058 次
发布时间:2019-05-25

本文共 4515 字,大约阅读时间需要 15 分钟。

GNU中的一个软件包,包名叫hello,呵呵,看来很简单啦。

今天就来分析一下,GNU的目的是通过这个说明一下,GNU标准软件包所应遵守的规则,以及一些必须的测试,编译脚本文件等。

俺就不分析其他的了,直接上最具价值的代码,其他忽略,这个程序实在是太小了,最重要的是一个getopt_long函数的应用,

用于解析命令行参数的。

#include <config.h>
#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);
}

转载地址:http://jczji.baihongyu.com/

你可能感兴趣的文章
C# 托管与非托管
查看>>
Node.js中的事件驱动编程详解
查看>>
mongodb 命令
查看>>
MongoDB基本使用
查看>>
mongodb管理与安全认证
查看>>
nodejs内存控制
查看>>
nodejs Stream使用中的陷阱
查看>>
MongoDB 数据文件备份与恢复
查看>>
数据库索引介绍及使用
查看>>
MongoDB数据库插入、更新和删除操作详解
查看>>
MongoDB文档(Document)全局唯一ID的设计思路
查看>>
mongoDB简介
查看>>
Redis持久化存储(AOF与RDB两种模式)
查看>>
memcached工作原理与优化建议
查看>>
Redis与Memcached的区别
查看>>
redis sharding方案
查看>>
程序员最核心的竞争力是什么?
查看>>
Node.js机制及原理理解初步
查看>>
linux CPU个数查看
查看>>
分布式应用开发相关的面试题收集
查看>>