Chinaunix首页 | 论坛 | 博客
  • 博客访问: 916683
  • 博文数量: 177
  • 博客积分: 8613
  • 博客等级: 中将
  • 技术积分: 2835
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-12 04:16
文章分类
文章存档

2012年(12)

2011年(24)

2010年(24)

2009年(75)

2008年(42)

我的朋友

分类: C/C++

2009-11-05 21:12:27

/* printenv -- print all or part of environment

打印全部或者一部分环境变量
     */

/* Usage: printenv [variable...]

   If no arguments are given, print the entire environment.
   If one or more variable names are given, print the value of
   each one that is set, and nothing for ones that are not set.

   Exit status:
   0 if all variables specified were found
   1 if not
   2 if some other error occurred

   David MacKenzie and Richard Mlynarik */
//包含4个标准头文件
#include
#include
#include
#include
//包含进来3个本地的头文件
#include "system.h"
#include "error.h"
#include "long-options.h"

/* Exit status for syntax errors, etc.  */
enum { PRINTENV_FAILURE = 2 }; //定义一个枚举类型的变量,PRINTENV_FAILURE,值为2,用途是返回语法错误时的程序退出状态

/* The official name of this program (e.g., no `g' prefix).  */
#define PROGRAM_NAME "printenv" //定义宏PROGRAM_NAME,其值为一个字符串,意义为程序名称

#define AUTHORS "David MacKenzie", "Richard Mlynarik"//定义宏AUTHORS,其值为2个字符串

/* The name this program was run with. */
char *program_name;//定义字符指针变量

extern char **environ;//定义外部指向字符指针的指针变量

void
usage (int status)//帮助函数
{
  if (status != EXIT_SUCCESS)//如果形参status不等于EXIT_SUCCESS,则打印一个字符串到标准错误,提示使用--help
    fprintf (stderr, _("Try `%s --help' for more information.\n"),
         program_name);
  else//否则,如果status等于EXIT_SUCCESS,则打印下面的语句块里的字符串
    {
      printf (_("\
Usage: %s [VARIABLE]...\n\
  or:  %s OPTION\n\
If no environment VARIABLE specified, print them all.\n\
\n\
"),
          program_name, program_name);//这句话表达了程序的用途,如果没有写明打印什么,则打印所有
      fputs (HELP_OPTION_DESCRIPTION, stdout);
      fputs (VERSION_OPTION_DESCRIPTION, stdout);
      printf (USAGE_BUILTIN_WARNING, PROGRAM_NAME);
      printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
    }
  exit (status);//usage帮助函数的退出状态是得到的形参status的值,注意这里直接退出了程序,而不是返回到main函数
}

int
main (int argc, char **argv)//标准的main函数
{
  char **env;//声明指向字符指针的指针变量env
  char *ep, *ap;//声明两个字符指针变量ep和ap
  int i;//声明整型变量i
  bool ok;//定义布尔类型变量ok,注意bool这个类型是在非标准头文件里定义的

  initialize_main (&argc, &argv);//初始化命令行参数
  program_name = argv[0];//将命令行参数的第一个,一般是程序名称,赋值给字符指针变量program_name
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  initialize_exit_failure (PRINTENV_FAILURE);
  /*
这是在system.h里面定义的函数,如果形参不等于EXIT_FAILURE,则为exit_failure赋值,值为形参的值
  */
  atexit (close_stdout);//登记出口函数

  parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
              usage, AUTHORS, (char const *) NULL);//解析命令行长选项,主要是为了打印帮助
  if (getopt_long (argc, argv, "+", NULL, NULL) != -1)//如果调用getopt_long没有正常结束
    usage (PRINTENV_FAILURE);//则调用帮助函数

  if (optind >= argc)//调用getopt_long后会得到optind的值,如果这个值大于或者等于argc的值
    {则遍历environ这个字符指针,并打印在标准输出上,至于environ是个外部变量,是怎么得到的,得继续看
      for (env = environ; *env != NULL; ++env)
    puts (*env);
      ok = true;//循环结束后,将布尔变量ok的值设置为true
    }
  else//否则,如果optind的值小于argc的值,则执行下面的语句块,我写了个测试程序,发现只要写了程序名,optind就一直是1了
    {
      int matches = 0;//初始化一个整型变量matches,初始值为0,然后开始一个循环

      for (i = optind; i < argc; ++i)//循环的条件是从optind开始,到argc
    {
      bool matched = false;//在循环开始的时候设置布尔变量matched,其值为false

      for (env = environ; *env; ++env)//和上面打印全部环境变量的循环一致,遍历一遍所有的环境变量
        {
          ep = *env;//ep是个字符指针变量,它得到的值是当前循环里的*environ的值
          ap = argv[i];//ap也是个字符指针变量,它得到的值是命令行选项的某个当前i变量对应的字符串
          while (*ep != '\0' && *ap != '\0' && *ep++ == *ap++)//又是一个循环,条件是,如果环境变量不是空并且命令行选项不是空,并且环境变量等于命令行选项
        {
          if (*ep == '=' && *ap == '\0')//在while的条件里,ep和ap都执行了自增操作,ep是环境变量,它自增后如果是字符=,并且命令行选项自增后的对应是空
            {
              puts (ep + 1);//则打印环境变量里=符号后面的内容
              matched = true;//修改布尔变量matched的值,改变为true,意思是找到了一个环境变量符合命令行选项里给的字符串
              break;//找到一个并打印出来以后,立即退出循环,进行下一个environ的判断
            }
        }
        }

      matches += matched;//增加匹配到的个数
    }

      ok = (matches == argc - optind);//ok是一个布尔值
    }

  exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);//根据ok的值,得到退出状态。
}


----------------
    这个程序实现的功能和env、set等是一样的,程序的关键点是调用了一个extern的全局变量,对这个变量进行读操作。
阅读(1614) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~