【原】命令行参数解析及配置编程流程范式

2018-06-17 21:46:36来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

在研读Bitshares 2.0的开源代码时,大大惊异于witness_node主函数中关于命令行参数解析配置的优秀流程。这里就将代码贴出来进行欣赏:

 1  namespace bpo = boost::program_options;
 2  
 3    ...............
 4    ...............
 5   int main(int argc, char** argv) {
 6      app::application* node = new app::application();
 7     fc::oexception unhandled_exception;
 8 
 9     try {
10        bpo::options_description app_options("Graphene Witness Node");
11        bpo::options_description cfg_options("Graphene Witness Node");
12        app_options.add_options()
13             ("help,h", "Print this help message and exit.")
14              ("data-dir,d", bpo::value<boost::filesystem::path>()->default_value("witness_node_data_dir"), "Directory containing databases, configuration file, etc.")
15             ;
16 
17        bpo::variables_map options;
18 
19    ...............
20    ...............
21 
22  
23 
24  try  { 
25   bpo::options_description cli, cfg; 
26  //cli, cfg 都是外部参数,将cli, cfg放入set_program_options函数中,对这两个参数进行配置,然后放入app_options.add()函数中 
27   node->set_program_options(cli, cfg); 
28   app_options.add(cli); 
29  //cfg_options此处的配置并没有立即使用,在这个作用域中,配置完app_options和cfg_options之后,cli, cfg 这两个参数就释放掉了。 
30   cfg_options.add(cfg); 34 //这里只用了app_options,但是,cfg的内容在set_program_options()函数中就全部加入到cli中了。 
31   bpo::store(bpo::parse_command_line(argc, argv, app_options), options); 
32  
33   } 
34  catch (const boost::program_options::error& e) 
35   { 
36  std::cerr << "Error parsing command line: " << e.what() << "\n"; 
37  return 1; 
38  }
39 
40    ...............
41    ...............
42  } catch( const fc::exception& e ) {
43       // deleting the node can yield, so do this outside the exception handler
44       unhandled_exception = e;
45    }
46 
47    if (unhandled_exception)
48    {
49       elog("Exiting with error:\n${e}", ("e", unhandled_exception->to_detail_string()));
50       node->shutdown();
51       delete node;
52       return 1;
53    }

 

 第一步:设置全局变量

namespace bpo = boost::program_options;

这样方便后面描述,简化代码,易于阅读。放在main函数之前,作为全局的变量声明。

第二部:进入主程序后,定义异常变量

fc::oexception unhandled_exception;

当然,也可以直接使用 STL库或者boost中的相关类。这里提供一个基本范式,fc是Bitshares源代码自带的一个Fast-Compiling-Library,简称FC,提供了很多Boost库中类似的功能,但是针对于具体的工程做了裁剪。因为Bitshares本身也是一个开发框架。

第三步:搭建try...catch..框架

try  { 
  ............ }
catch( ClassType& e ) { // deleting the node can yield, so do this outside the exception handler unhandled_exception = e; }

第四步: 声明一个options_description类的实例,参数可以设置为主程序名称。

然后利用add_options()函数添加内容;后名一个括号为一个添加项,在函数末尾要加上“;”。括号中地一个参数为程序命令行需要附加的设置参数。“ ”中第一项为全称,执行时前面加上“--”;第二项为简称,执行时前面加上“-”。

bpo::options_description app_options("Graphene Witness Node");
app_options.add_options()
      ("help,h", "Print this help message and exit.")
      ("data-dir,d", bpo::value<boost::filesystem::path>()->default_value("witness_node_data_dir"), "Directory containing databases, configuration file, etc.");

不过,在很多特殊情况下,还可以使用add函数追加显示内容,但是要首先声明options_description类的容器,编写函数对其中内容进行添加,这些内容可以来自于直接设置的命令行字符串,也可来自于ini文件。

bpo::options_description cli, cfg; 
node->set_program_options(cli, cfg); 
app_options.add(cli); 

这个例子程序中编写了一个set_program_options函数,使用node->对其进行重载。

第五步:声明一个variables_map变量,用于容纳解析后的数据,然后使用parse_command_line进行解析,并使用store函数将解析出的结果保存在variables_map容器中,就完成了基本功能。

 

bpo::variables_map options;
bpo::store(bpo::parse_command_line(argc, argv, app_options), options); 

 

parse_command_line有三个参数,argc和argv来自与主程序,app_options中存储了已经添加的命令和需要显示的信息。

当然,如果添加的信息来自于ini配置文件,则也可以使用parse_config_file函数对app_options进行解析。

第六步,对异常进行处理

 

catch( const fc::exception& e ) {
      // deleting the node can yield, so do this outside the exception handler
      unhandled_exception = e;
   }

   if (unhandled_exception)
   {
      elog("Exiting with error:\n${e}", ("e", unhandled_exception->to_detail_string()));
      node->shutdown();
      delete node;
      return 1;
   }

这里使用elog对异常进行显示,将if处理放在外面,可以使得程序显得更加简洁清晰,而且还可以在前面添加更多的try...catch...结构。

这个编程流程范式非常简单、实用、安全、完备,可以在其他任务中套用。

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:linux下socket编程常用头文件

下一篇:【codevs2822】爱在心中