docopt / docopt.cpp

C++11 port of docopt
Boost Software License 1.0
1.04k stars 146 forks source link

A single header version? #96

Open qelewere opened 6 years ago

qelewere commented 6 years ago

Could we have a single header version of DOCOPT without any external dependencies (other than STL), please?

myd7349 commented 6 years ago

May be defining DOCOPT_HEADER_ONLY before including docopt.h is an option.

If you want everything appears in a single heder file, take a look at Amalgamate. :-)

Related issue: #37

erichschroeter commented 6 years ago

I gave Amalgamate a shot.

  1. Compiled Amalgamate.
  2. Executed the following command: Amalgamate.exe -i /path/to/docopt.cpp/ /path/to/docopt.cpp/docopt.h /path/to/docopt.cpp/docopt.hpp
  3. Copied the docopt.hpp to my project.
  4. Added #define DOCOPT_HEADER_ONLY
  5. Added #include "docopt.hpp"
  6. Added the example docopt.cpp code to test it out.
  7. Compiled and got a bunch of compiler errors.
[build]        "C:\src\build\ALL_BUILD.vcxproj" (default target) (1) ->
[build]        "C:\src\build\Target\myproject\config_export.vcxproj" (default target) (8) ->
[build]        (ClCompile target) -> 
[build]          c:\src\target\myproject\src\docopt.hpp(2090): error C2039: 'regex': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2090): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2090): error C2146: syntax error: missing ';' before identifier 're_separators' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2090): error C2065: 're_separators': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2098): error C2039: 'regex': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2098): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2098): error C2086: 'const int regex': redefinition [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2098): error C2146: syntax error: missing ';' before identifier 're_strings' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2098): error C2065: 're_strings': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2113): error C2039: 'sregex_iterator': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2113): error C2065: 'sregex_iterator': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2113): error C2065: 're_separators': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2114): error C2039: 'sregex_iterator': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2114): error C2065: 'sregex_iterator': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2115): error C2039: 'smatch': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2115): error C2061: syntax error: identifier 'smatch' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2118): error C2065: 'match': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2118): error C2228: left of '.prefix' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2118): error C2228: left of '.matched' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2119): error C2039: 'sregex_iterator': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2119): error C2065: 'sregex_iterator': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2119): error C2065: 'match': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2119): error C2228: left of '.prefix' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2119): error C2228: left of '.first' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2119): error C2228: left of '.second' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2119): error C2065: 're_strings': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2120): error C2039: 'sregex_iterator': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2120): error C2065: 'sregex_iterator': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2121): error C2039: 'smatch': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2121): error C2061: syntax error: identifier 'smatch' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2123): error C2065: 'm': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2123): error C2228: left of '.str' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2128): error C2065: 'match': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2128): error C2228: left of '.matched' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2129): error C2065: 'match': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2129): error C2228: left of '.str' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2147): error C3861: 'join': identifier not found [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2168): error C2065: 'Pattern': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2168): error C2065: 'pattern': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2168): error C2447: '{': missing function header (old-style formal list?) [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2186): error C2039: 'regex': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2186): error C2065: 'regex': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2186): error C2143: syntax error: missing ';' before 'const' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2186): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2192): error C2039: 'regex': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2192): error C3083: 'regex': the symbol to the left of a '::' must be a type [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2192): error C2039: 'icase': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2193): error C2065: 'icase': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2193): error C2440: 'initializing': cannot convert from 'initializer list' to 'int' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2196): error C2039: 'sregex_iterator': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2196): error C3861: 'sregex_iterator': identifier not found [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2197): error C2039: 'sregex_iterator': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2197): error C3861: 'sregex_iterator': identifier not found [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2198): error C2039: 'smatch': is not a member of 'std' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2198): error C2061: syntax error: identifier 'smatch' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2200): error C2065: 'match': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2200): error C2228: left of '.str' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2200): error C3861: 'trim': identifier not found [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2228): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2228): error C2146: syntax error: missing ';' before identifier 'parse_long' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2228): error C2065: 'Option': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2228): error C2923: 'std::vector': 'Option' is not a valid template type argument for parameter '_Ty' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2228): error C3203: 'allocator': unspecialized class template can't be used as a template argument for template parameter '_Alloc', expected a real type [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2229): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2233): error C2672: 'partition': no matching overloaded function found [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2233): error C2780: '_FwdIt std::partition(_FwdIt,const _FwdIt,_Pr)': expects 3 arguments - 2 provided [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2235): error C3861: 'starts_with': identifier not found [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2242): error C2065: 'Option': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2242): error C2059: syntax error: 'const' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2242): error C2923: 'std::vector': 'Option' is not a valid template type argument for parameter '_Ty' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2242): error C3203: 'allocator': unspecialized class template can't be used as a template argument for template parameter '_Alloc', expected a real type [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2242): error C2133: 'similar': unknown size [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2242): error C2512: 'std::vector': no appropriate default constructor available [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2243): error C2663: 'std::vector<_Ty,_Alloc>::_Unchecked_begin': 2 overloads have no legal conversion for 'this' pointer [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2243): error C2663: 'std::vector<_Ty,_Alloc>::_Unchecked_end': 2 overloads have no legal conversion for 'this' pointer [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2243): error C3536: '<begin>$L0': cannot be used before it is initialized [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2243): error C3536: '<end>$L0': cannot be used before it is initialized [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2243): error C2100: illegal indirection [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2244): error C2228: left of '.longOption' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2245): error C2663: 'std::vector<_Ty,_Alloc>::push_back': 2 overloads have no legal conversion for 'this' pointer [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2249): error C2662: 'bool std::vector<_Ty,_Alloc>::empty(void) noexcept const': cannot convert 'this' pointer from 'std::vector' to 'const std::vector<_Ty,_Alloc> &' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2250): error C2663: 'std::vector<_Ty,_Alloc>::_Unchecked_begin': 2 overloads have no legal conversion for 'this' pointer [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2250): error C2663: 'std::vector<_Ty,_Alloc>::_Unchecked_end': 2 overloads have no legal conversion for 'this' pointer [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2250): error C3536: '<begin>$L1': cannot be used before it is initialized [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2250): error C3536: '<end>$L1': cannot be used before it is initialized [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2250): error C2100: illegal indirection [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2251): error C2228: left of '.longOption' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2251): error C2228: left of '.empty' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2253): error C2228: left of '.longOption' must have class/struct/union [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2253): error C3861: 'starts_with': identifier not found [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2254): error C2663: 'std::vector<_Ty,_Alloc>::push_back': 2 overloads have no legal conversion for 'this' pointer [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2258): error C2146: syntax error: missing ';' before identifier 'ret' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2258): error C2065: 'ret': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2260): error C2662: '_Vector_alloc<_Alloc_types>::_Val_types::size_type std::vector<_Ty,_Alloc>::size(void) noexcept const': cannot convert 'this' pointer from 'std::vector' to 'const std::vector<_Ty,_Alloc> &' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2261): error C2663: 'std::vector<_Ty,_Alloc>::begin': 2 overloads have no legal conversion for 'this' pointer [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2261): error C2663: 'std::vector<_Ty,_Alloc>::end': 2 overloads have no legal conversion for 'this' pointer [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2261): error C2672: 'longOptions': no matching overloaded function found [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2261): error C2780: 'std::vector<std::string,std::allocator<_Ty>> longOptions(I,I)': expects 2 arguments - 1 provided [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2263): error C3861: 'join': identifier not found [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2265): error C2662: 'bool std::vector<_Ty,_Alloc>::empty(void) noexcept const': cannot convert 'this' pointer from 'std::vector' to 'const std::vector<_Ty,_Alloc> &' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2267): error C2662: 'decltype(auto) std::vector<_Ty,_Alloc>::emplace_back<const char(&)[1],std::string&,int&>(const char (&)[1],std::string &,int &)': cannot convert 'this' pointer from 'std::vector' to 'std::vector<_Ty,_Alloc> &' [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2269): error C2065: 'Option': undeclared identifier [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2269): error C2663: 'std::vector<_Ty,_Alloc>::back': 2 overloads have no legal conversion for 'this' pointer [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2269): error C2672: 'std::make_shared': no matching overloaded function found [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2269): error C2974: 'std::make_shared': invalid template argument for '_Ty', type expected [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2271): error C3536: 'o': cannot be used before it is initialized [C:\src\build\Target\myproject\config_export.vcxproj]
[build]          c:\src\target\myproject\src\docopt.hpp(2271): fatal error C1003: error count exceeds 100; stopping compilation [C:\src\build\Target\myproject\config_export.vcxproj]
[build] 
[build]     1 Warning(s)
[build]     107 Error(s)
[build] 
[build] Time Elapsed 00:00:01.39
[build] Build finished with exit code 1
indianakernick commented 4 years ago

I started working on this and I got something that seems to work. See for yourself. Though the problem is that docopt is not written as a header-only library. Simply defining DOCOPT_HEADER_ONLY will appear to work but the usage of static and anonymous namespaces in a header file could lead to name collisions. Doing this properly would involve converting docopt to a full header-only library (and using docopt::detail instead of anonymous namespaces).

I'm considering doing the conversion but I'd like to hear what others think on the matter.


I just noticed a using namespace docopt. We definitely don't want that in a header!

jaredgrubb commented 4 years ago

Yeh .. I'm open to something like that. Nlohmann json has that.

The downside is that people that make patches have an extra step (to generate the header) and may accidentally patch the single-header and have to redo their patch. But it works for them, so it might be ok.