response_file.cpp 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // Copyright Vladimir Prus 2002-2004.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt
  4. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. /** This example shows how to handle response file.
  6. For a test, build and run:
  7. response_file -I foo @response_file.rsp
  8. The expected output is:
  9. Include paths: foo bar biz
  10. Thanks to Hartmut Kaiser who raised the issue of response files
  11. and discussed the possible approach.
  12. */
  13. #include <boost/program_options/options_description.hpp>
  14. #include <boost/program_options/parsers.hpp>
  15. #include <boost/program_options/variables_map.hpp>
  16. #include <boost/tokenizer.hpp>
  17. #include <boost/token_functions.hpp>
  18. using namespace boost;
  19. using namespace boost::program_options;
  20. #include <iostream>
  21. #include <fstream>
  22. using namespace std;
  23. // Additional command line parser which interprets '@something' as a
  24. // option "config-file" with the value "something"
  25. pair<string, string> at_option_parser(string const&s)
  26. {
  27. if ('@' == s[0])
  28. return std::make_pair(string("response-file"), s.substr(1));
  29. else
  30. return pair<string, string>();
  31. }
  32. int main(int ac, char* av[])
  33. {
  34. try {
  35. options_description desc("Allowed options");
  36. desc.add_options()
  37. ("help", "produce a help message")
  38. ("include-path,I", value< vector<string> >()->composing(),
  39. "include path")
  40. ("magic", value<int>(), "magic value")
  41. ("response-file", value<string>(),
  42. "can be specified with '@name', too")
  43. ;
  44. variables_map vm;
  45. store(command_line_parser(ac, av).options(desc)
  46. .extra_parser(at_option_parser).run(), vm);
  47. if (vm.count("help")) {
  48. cout << desc;
  49. }
  50. if (vm.count("response-file")) {
  51. // Load the file and tokenize it
  52. ifstream ifs(vm["response-file"].as<string>().c_str());
  53. if (!ifs) {
  54. cout << "Could not open the response file\n";
  55. return 1;
  56. }
  57. // Read the whole file into a string
  58. stringstream ss;
  59. ss << ifs.rdbuf();
  60. // Split the file content
  61. char_separator<char> sep(" \n\r");
  62. string sstr = ss.str();
  63. tokenizer<char_separator<char> > tok(sstr, sep);
  64. vector<string> args;
  65. copy(tok.begin(), tok.end(), back_inserter(args));
  66. // Parse the file and store the options
  67. store(command_line_parser(args).options(desc).run(), vm);
  68. }
  69. if (vm.count("include-path")) {
  70. const vector<string>& s = vm["include-path"].as<vector< string> >();
  71. cout << "Include paths: ";
  72. copy(s.begin(), s.end(), ostream_iterator<string>(cout, " "));
  73. cout << "\n";
  74. }
  75. if (vm.count("magic")) {
  76. cout << "Magic value: " << vm["magic"].as<int>() << "\n";
  77. }
  78. }
  79. catch (std::exception& e) {
  80. cout << e.what() << "\n";
  81. }
  82. }