arguments.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #pragma once
  2. #include <nall/location.hpp>
  3. #include <nall/path.hpp>
  4. #include <nall/string.hpp>
  5. #include <nall/vector.hpp>
  6. namespace nall {
  7. struct Arguments {
  8. Arguments(int argc, char** argv);
  9. Arguments(vector<string> arguments);
  10. explicit operator bool() const { return (bool)arguments; }
  11. auto size() const -> uint { return arguments.size(); }
  12. auto operator[](uint index) -> string& { return arguments[index]; }
  13. auto operator[](uint index) const -> const string& { return arguments[index]; }
  14. auto programPath() const -> string;
  15. auto programName() const -> string;
  16. auto programLocation() const -> string;
  17. auto find(string_view name) const -> bool;
  18. auto find(string_view name, bool& argument) const -> bool;
  19. auto find(string_view name, string& argument) const -> bool;
  20. auto begin() const { return arguments.begin(); }
  21. auto end() const { return arguments.end(); }
  22. auto rbegin() const { return arguments.rbegin(); }
  23. auto rend() const { return arguments.rend(); }
  24. auto take() -> string;
  25. auto take(string_view name) -> bool;
  26. auto take(string_view name, bool& argument) -> bool;
  27. auto take(string_view name, string& argument) -> bool;
  28. auto begin() { return arguments.begin(); }
  29. auto end() { return arguments.end(); }
  30. auto rbegin() { return arguments.rbegin(); }
  31. auto rend() { return arguments.rend(); }
  32. private:
  33. auto construct() -> void;
  34. string programArgument;
  35. vector<string> arguments;
  36. };
  37. inline auto Arguments::construct() -> void {
  38. if(!arguments) return;
  39. //extract and pre-process program argument
  40. programArgument = arguments.takeFirst();
  41. programArgument = {Path::real(programArgument), Location::file(programArgument)};
  42. //normalize path and file arguments
  43. for(auto& argument : arguments) {
  44. if(directory::exists(argument)) argument.transform("\\", "/").trimRight("/").append("/");
  45. else if(file::exists(argument)) argument.transform("\\", "/").trimRight("/");
  46. }
  47. }
  48. inline Arguments::Arguments(int argc, char** argv) {
  49. #if defined(PLATFORM_WINDOWS)
  50. utf8_arguments(argc, argv);
  51. #endif
  52. for(uint index : range(argc)) arguments.append(argv[index]);
  53. construct();
  54. }
  55. inline Arguments::Arguments(vector<string> arguments) {
  56. this->arguments = arguments;
  57. construct();
  58. }
  59. inline auto Arguments::programPath() const -> string {
  60. return Location::path(programArgument);
  61. }
  62. inline auto Arguments::programName() const -> string {
  63. return Location::file(programArgument);
  64. }
  65. inline auto Arguments::programLocation() const -> string {
  66. return programArgument;
  67. }
  68. inline auto Arguments::find(string_view name) const -> bool {
  69. for(uint index : range(arguments.size())) {
  70. if(arguments[index].match(name)) {
  71. return true;
  72. }
  73. }
  74. return false;
  75. }
  76. inline auto Arguments::find(string_view name, bool& argument) const -> bool {
  77. for(uint index : range(arguments.size())) {
  78. if(arguments[index].match(name) && arguments.size() >= index
  79. && (arguments[index + 1] == "true" || arguments[index + 1] == "false")) {
  80. argument = arguments[index + 1] == "true";
  81. return true;
  82. }
  83. }
  84. return false;
  85. }
  86. inline auto Arguments::find(string_view name, string& argument) const -> bool {
  87. for(uint index : range(arguments.size())) {
  88. if(arguments[index].match(name) && arguments.size() >= index) {
  89. argument = arguments[index + 1];
  90. return true;
  91. }
  92. }
  93. return false;
  94. }
  95. //
  96. inline auto Arguments::take() -> string {
  97. if(!arguments) return {};
  98. return arguments.takeFirst();
  99. }
  100. inline auto Arguments::take(string_view name) -> bool {
  101. for(uint index : range(arguments.size())) {
  102. if(arguments[index].match(name)) {
  103. arguments.remove(index);
  104. return true;
  105. }
  106. }
  107. return false;
  108. }
  109. inline auto Arguments::take(string_view name, bool& argument) -> bool {
  110. for(uint index : range(arguments.size())) {
  111. if(arguments[index].match(name) && arguments.size() > index + 1
  112. && (arguments[index + 1] == "true" || arguments[index + 1] == "false")) {
  113. arguments.remove(index);
  114. argument = arguments.take(index) == "true";
  115. return true;
  116. }
  117. }
  118. return false;
  119. }
  120. inline auto Arguments::take(string_view name, string& argument) -> bool {
  121. for(uint index : range(arguments.size())) {
  122. if(arguments[index].match(name) && arguments.size() > index + 1) {
  123. arguments.remove(index);
  124. argument = arguments.take(index);
  125. return true;
  126. }
  127. }
  128. return false;
  129. }
  130. }