You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
5.3 KiB

2 years ago
  1. /*****************************************************************************
  2. *
  3. * CLIPP - command line interfaces for modern C++
  4. *
  5. * released under MIT license
  6. *
  7. * (c) 2017-2018 André Müller; foss@andremueller-online.de
  8. *
  9. *****************************************************************************/
  10. #include "testing.h"
  11. //-------------------------------------------------------------------
  12. void test(int lineNo, bool expected, const clipp::group& cli)
  13. {
  14. if(cli.flags_are_prefix_free() != expected) {
  15. std::cout << "prefix '" << cli.common_flag_prefix() << "'" << std::endl;
  16. throw std::runtime_error{"failed test " + std::string(__FILE__) +
  17. " in line " + std::to_string(lineNo)};
  18. }
  19. }
  20. //-------------------------------------------------------------------
  21. clipp::group
  22. make_cli_1()
  23. {
  24. using namespace clipp;
  25. auto copyMode = "copy mode:" % (
  26. command("copy") | command("move"),
  27. option("--all") % "copy all",
  28. option("--replace") % "replace existing files",
  29. option("-f", "--force") % "don't ask for confirmation"
  30. );
  31. auto compareMode = "compare mode:" % (
  32. command("compare"),
  33. (command("date") | command("content")),
  34. option("-b", "--binary") % "compare files byte by byte",
  35. option("-q", "--quick") % "use heuristics for faster comparison"
  36. );
  37. auto mergeAlgo = (
  38. command("diff") % "merge using diff" |
  39. command("patch") % "merge using patch" |
  40. ( command("inside") % "merge based on content",
  41. "content based merge options:" % (
  42. option("--git-style") % "emulate git's merge behavior",
  43. option("-m", "--marker") & value("marker") % "merge marker symbol"
  44. )
  45. )
  46. );
  47. auto mergeMode = "merge mode:" % (
  48. command("merge"),
  49. mergeAlgo,
  50. required("-o") & value("outdir") % "target directory for merge result",
  51. option("--show-conflicts") % "show merge conflicts during run"
  52. );
  53. auto firstOpt = "user interface options:" % (
  54. option("-v", "--verbose") % "show detailed output",
  55. option("-i", "--interactive") % "use interactive mode"
  56. );
  57. auto lastOpt = "mode-independent options:" % (
  58. values("files") % "input files",
  59. option("-r", "--recursive") % "descend into subdirectories",
  60. option("-h", "--help") % "show help"
  61. );
  62. return (
  63. firstOpt,
  64. copyMode | compareMode | mergeMode | command("list"),
  65. lastOpt);
  66. }
  67. //-------------------------------------------------------------------
  68. int main()
  69. {
  70. using namespace clipp;
  71. try {
  72. test( __LINE__ , true, group{} );
  73. test( __LINE__ , true, ( option("-a"), option("-b") ));
  74. test( __LINE__ , true, ( option(""), option("-b") ));
  75. test( __LINE__ , true, ( option("-a"), option("") ));
  76. test( __LINE__ , true, ( option("-a"), option("-b"), option("--a") ));
  77. test( __LINE__ , true, ( option(""), option("-b"), option("--a") ));
  78. test( __LINE__ , true, ( option("-a"), option(""), option("--a") ));
  79. test( __LINE__ , true, ( option("-a"), option("-b"), option("") ));
  80. test( __LINE__ , true, (
  81. option("-a"), option("--a"), option("-b"), option("--b")
  82. ));
  83. test( __LINE__ , true, (
  84. option("-a"), option("--a-a"), option("-b"), option("--b-b")
  85. ));
  86. test( __LINE__ , true, (
  87. (option("-a"), option("--a-a")) % "a",
  88. (option("-b"), option("--b-b")) % "b"
  89. ));
  90. test( __LINE__ , true, ( value("-a"), option("-a"), option("-b") ));
  91. test( __LINE__ , true, ( option("-a"), value("-a"), option("-b") ));
  92. test( __LINE__ , true, ( option("-a"), option("-b"), value("-b") ));
  93. test( __LINE__ , true, ( option("-a"), option("-b"), value("") ));
  94. test( __LINE__ , true, (
  95. option("-a"), option("--a"), option("-b"), value("-b"), option("--b")
  96. ));
  97. test( __LINE__ , true, (
  98. option("-a"), option("--a-a"), option("-b"), option("--b-b")
  99. ));
  100. test( __LINE__ , true, (
  101. (option("-a"), option("--a-a")) % "a",
  102. (option("-b"), option("--b-b")) % "b"
  103. ));
  104. //same flags are not an error - TODO is this OK?
  105. test( __LINE__ , true, (
  106. (option("-a"), option("-a")) % "a",
  107. (option("-b"), option("-b")) % "b"
  108. ));
  109. test( __LINE__ , true, (
  110. (option("-a") & value("-a"), option("--a-a")) % "a",
  111. (option("-b"), option("--b-b") & values("-a")) % "b"
  112. ));
  113. test( __LINE__ , false, ( option("-a"), option("-ab") ));
  114. test( __LINE__ , false, ( option("-ab"), option("-a") ));
  115. test( __LINE__ , false, (
  116. option("-a"), option("-aa"), option("-b"), option("--b-b")
  117. ));
  118. test( __LINE__ , false, (
  119. (option("-a"), option("--a")) % "a",
  120. (option("-b"), option("-abba")) % "b"
  121. ));
  122. test( __LINE__ , false, (
  123. (option("-a") & value("a"), option("--a")) % "a",
  124. (option("-b"), option("-abba") & values("-b")) % "b"
  125. ));
  126. test( __LINE__, true, make_cli_1() );
  127. }
  128. catch(std::exception& e) {
  129. std::cerr << e.what() << std::endl;
  130. return 1;
  131. }
  132. }