Commit f862849488557eeee0397814a47449ecfdae0383

Authored by Henry Schreiner
Committed by GitHub
1 parent 32e6c3f3

refactor: new version of MakeSingleFiles (#546)

* refactor: new version of MakeSingleFiles

* fix: use CMake and set version
.github/workflows/build.yml
@@ -22,11 +22,8 @@ jobs: @@ -22,11 +22,8 @@ jobs:
22 22
23 - uses: actions/setup-python@v2 23 - uses: actions/setup-python@v2
24 24
25 - - name: Make header  
26 - run: python ./scripts/MakeSingleHeader.py CLI11.hpp  
27 -  
28 - name: Prepare CMake config 25 - name: Prepare CMake config
29 - run: cmake -S . -B build 26 + run: cmake -S . -B build -DCLI11_SINGLE_FILE=ON
30 27
31 - name: Make package 28 - name: Make package
32 run: cmake --build build --target package_source 29 run: cmake --build build --target package_source
@@ -37,10 +34,13 @@ jobs: @@ -37,10 +34,13 @@ jobs:
37 cp build/CLI11-*-Source.* CLI11-Source 34 cp build/CLI11-*-Source.* CLI11-Source
38 cp build/CLI11-*-Source.* . 35 cp build/CLI11-*-Source.* .
39 36
  37 + - name: Make header
  38 + run: cmake --build build --target CLI11-generate-single-file
  39 +
40 - uses: actions/upload-artifact@v2 40 - uses: actions/upload-artifact@v2
41 with: 41 with:
42 name: CLI11.hpp 42 name: CLI11.hpp
43 - path: CLI11.hpp 43 + path: build/include/CLI11.hpp
44 44
45 - uses: actions/upload-artifact@v2 45 - uses: actions/upload-artifact@v2
46 with: 46 with:
CLI11.hpp.in 0 → 100644
  1 +// CLI11: Version {version}
  2 +// Originally designed by Henry Schreiner
  3 +// https://github.com/CLIUtils/CLI11
  4 +//
  5 +// This is a standalone header file generated by MakeSingleHeader.py in CLI11/scripts
  6 +// from: {git}
  7 +//
  8 +// CLI11 {version} Copyright (c) 2017-2020 University of Cincinnati, developed by Henry
  9 +// Schreiner under NSF AWARD 1414736. All rights reserved.
  10 +//
  11 +// Redistribution and use in source and binary forms of CLI11, with or without
  12 +// modification, are permitted provided that the following conditions are met:
  13 +//
  14 +// 1. Redistributions of source code must retain the above copyright notice, this
  15 +// list of conditions and the following disclaimer.
  16 +// 2. Redistributions in binary form must reproduce the above copyright notice,
  17 +// this list of conditions and the following disclaimer in the documentation
  18 +// and/or other materials provided with the distribution.
  19 +// 3. Neither the name of the copyright holder nor the names of its contributors
  20 +// may be used to endorse or promote products derived from this software without
  21 +// specific prior written permission.
  22 +//
  23 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24 +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25 +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  27 +// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28 +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29 +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30 +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32 +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33 +
  34 +// Standard combined includes:
  35 +{public_includes}
  36 +
  37 +{version_hpp}
  38 +
  39 +{macros_hpp}
  40 +
  41 +{validators_hpp_filesystem}
  42 +
  43 +namespace {namespace} {{
  44 +
  45 +{string_tools_hpp}
  46 +
  47 +{error_hpp}
  48 +
  49 +{type_tools_hpp}
  50 +
  51 +{split_hpp}
  52 +
  53 +{config_fwd_hpp}
  54 +
  55 +{validators_hpp}
  56 +
  57 +{formatter_fwd_hpp}
  58 +
  59 +{option_hpp}
  60 +
  61 +{app_hpp}
  62 +
  63 +{config_hpp}
  64 +
  65 +{formatter_hpp}
  66 +
  67 +}} // namespace {namespace}
CMakeLists.txt
@@ -247,7 +247,10 @@ if(CLI11_SINGLE_FILE) @@ -247,7 +247,10 @@ if(CLI11_SINGLE_FILE)
247 add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp" 247 add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp"
248 COMMAND Python::Interpreter 248 COMMAND Python::Interpreter
249 "${CMAKE_CURRENT_SOURCE_DIR}/scripts/MakeSingleHeader.py" 249 "${CMAKE_CURRENT_SOURCE_DIR}/scripts/MakeSingleHeader.py"
250 - "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp" 250 + ${CLI11_headers}
  251 + --main "${CMAKE_CURRENT_SOURCE_DIR}/CLI11.hpp.in"
  252 + --output "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp"
  253 + --version "${CLI11_VERSION}"
251 DEPENDS 254 DEPENDS
252 "${CMAKE_CURRENT_SOURCE_DIR}/include/CLI/CLI.hpp" 255 "${CMAKE_CURRENT_SOURCE_DIR}/include/CLI/CLI.hpp"
253 ${CLI11_headers}) 256 ${CLI11_headers})
include/CLI/App.hpp
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 6
7 #pragma once 7 #pragma once
8 8
  9 +// [CLI11:public_includes:set]
9 #include <algorithm> 10 #include <algorithm>
10 #include <cstdint> 11 #include <cstdint>
11 #include <functional> 12 #include <functional>
@@ -18,6 +19,7 @@ @@ -18,6 +19,7 @@
18 #include <string> 19 #include <string>
19 #include <utility> 20 #include <utility>
20 #include <vector> 21 #include <vector>
  22 +// [CLI11:public_includes:end]
21 23
22 // CLI Library includes 24 // CLI Library includes
23 #include "ConfigFwd.hpp" 25 #include "ConfigFwd.hpp"
@@ -30,6 +32,7 @@ @@ -30,6 +32,7 @@
30 #include "TypeTools.hpp" 32 #include "TypeTools.hpp"
31 33
32 namespace CLI { 34 namespace CLI {
  35 +// [CLI11:app_hpp:verbatim]
33 36
34 #ifndef CLI11_PARSE 37 #ifndef CLI11_PARSE
35 #define CLI11_PARSE(app, argc, argv) \ 38 #define CLI11_PARSE(app, argc, argv) \
@@ -3234,4 +3237,5 @@ struct AppFriend { @@ -3234,4 +3237,5 @@ struct AppFriend {
3234 }; 3237 };
3235 } // namespace detail 3238 } // namespace detail
3236 3239
  3240 +// [CLI11:app_hpp:end]
3237 } // namespace CLI 3241 } // namespace CLI
include/CLI/Config.hpp
@@ -6,19 +6,21 @@ @@ -6,19 +6,21 @@
6 6
7 #pragma once 7 #pragma once
8 8
  9 +// [CLI11:public_includes:set]
9 #include <algorithm> 10 #include <algorithm>
10 #include <fstream> 11 #include <fstream>
11 #include <iostream> 12 #include <iostream>
12 #include <string> 13 #include <string>
13 #include <utility> 14 #include <utility>
14 #include <vector> 15 #include <vector>
  16 +// [CLI11:public_includes:set]
15 17
16 #include "App.hpp" 18 #include "App.hpp"
17 #include "ConfigFwd.hpp" 19 #include "ConfigFwd.hpp"
18 #include "StringTools.hpp" 20 #include "StringTools.hpp"
19 21
20 namespace CLI { 22 namespace CLI {
21 - 23 +// [CLI11:config_hpp:verbatim]
22 namespace detail { 24 namespace detail {
23 25
24 inline std::string convert_arg_for_ini(const std::string &arg) { 26 inline std::string convert_arg_for_ini(const std::string &arg) {
@@ -348,4 +350,5 @@ ConfigBase::to_config(const App *app, bool default_also, bool write_description, @@ -348,4 +350,5 @@ ConfigBase::to_config(const App *app, bool default_also, bool write_description,
348 return out.str(); 350 return out.str();
349 } 351 }
350 352
  353 +// [CLI11:config_hpp:end]
351 } // namespace CLI 354 } // namespace CLI
include/CLI/ConfigFwd.hpp
@@ -6,16 +6,19 @@ @@ -6,16 +6,19 @@
6 6
7 #pragma once 7 #pragma once
8 8
  9 +// [CLI11:public_includes:set]
9 #include <algorithm> 10 #include <algorithm>
10 #include <fstream> 11 #include <fstream>
11 #include <iostream> 12 #include <iostream>
12 #include <string> 13 #include <string>
13 #include <vector> 14 #include <vector>
  15 +// [CLI11:public_includes:end]
14 16
15 #include "Error.hpp" 17 #include "Error.hpp"
16 #include "StringTools.hpp" 18 #include "StringTools.hpp"
17 19
18 namespace CLI { 20 namespace CLI {
  21 +// [CLI11:config_fwd_hpp:verbatim]
19 22
20 class App; 23 class App;
21 24
@@ -128,4 +131,5 @@ class ConfigINI : public ConfigTOML { @@ -128,4 +131,5 @@ class ConfigINI : public ConfigTOML {
128 valueDelimiter = '='; 131 valueDelimiter = '=';
129 } 132 }
130 }; 133 };
  134 +// [CLI11:config_fwd_hpp:end]
131 } // namespace CLI 135 } // namespace CLI
include/CLI/Error.hpp
@@ -6,16 +6,19 @@ @@ -6,16 +6,19 @@
6 6
7 #pragma once 7 #pragma once
8 8
  9 +// [CLI11:public_includes:set]
9 #include <exception> 10 #include <exception>
10 #include <stdexcept> 11 #include <stdexcept>
11 #include <string> 12 #include <string>
12 #include <utility> 13 #include <utility>
13 #include <vector> 14 #include <vector>
  15 +// [CLI11:public_includes:end]
14 16
15 // CLI library includes 17 // CLI library includes
16 #include "StringTools.hpp" 18 #include "StringTools.hpp"
17 19
18 namespace CLI { 20 namespace CLI {
  21 +// [CLI11:error_hpp:verbatim]
19 22
20 // Use one of these on all error classes. 23 // Use one of these on all error classes.
21 // These are temporary and are undef'd at the end of this file. 24 // These are temporary and are undef'd at the end of this file.
@@ -344,4 +347,5 @@ class OptionNotFound : public Error { @@ -344,4 +347,5 @@ class OptionNotFound : public Error {
344 347
345 /// @} 348 /// @}
346 349
  350 +// [CLI11:error_hpp:end]
347 } // namespace CLI 351 } // namespace CLI
include/CLI/Formatter.hpp
@@ -6,14 +6,17 @@ @@ -6,14 +6,17 @@
6 6
7 #pragma once 7 #pragma once
8 8
  9 +// [CLI11:public_includes:set]
9 #include <algorithm> 10 #include <algorithm>
10 #include <string> 11 #include <string>
11 #include <vector> 12 #include <vector>
  13 +// [CLI11:public_includes:end]
12 14
13 #include "App.hpp" 15 #include "App.hpp"
14 #include "FormatterFwd.hpp" 16 #include "FormatterFwd.hpp"
15 17
16 namespace CLI { 18 namespace CLI {
  19 +// [CLI11:formatter_hpp:verbatim]
17 20
18 inline std::string 21 inline std::string
19 Formatter::make_group(std::string group, bool is_positional, std::vector<const Option *> opts) const { 22 Formatter::make_group(std::string group, bool is_positional, std::vector<const Option *> opts) const {
@@ -285,4 +288,5 @@ inline std::string Formatter::make_option_usage(const Option *opt) const { @@ -285,4 +288,5 @@ inline std::string Formatter::make_option_usage(const Option *opt) const {
285 return opt->get_required() ? out.str() : "[" + out.str() + "]"; 288 return opt->get_required() ? out.str() : "[" + out.str() + "]";
286 } 289 }
287 290
  291 +// [CLI11:formatter_hpp:end]
288 } // namespace CLI 292 } // namespace CLI
include/CLI/FormatterFwd.hpp
@@ -6,14 +6,17 @@ @@ -6,14 +6,17 @@
6 6
7 #pragma once 7 #pragma once
8 8
  9 +// [CLI11:public_includes:set]
9 #include <map> 10 #include <map>
10 #include <string> 11 #include <string>
11 #include <utility> 12 #include <utility>
12 #include <vector> 13 #include <vector>
  14 +// [CLI11:public_includes:end]
13 15
14 #include "StringTools.hpp" 16 #include "StringTools.hpp"
15 17
16 namespace CLI { 18 namespace CLI {
  19 +// [CLI11:formatter_fwd_hpp:verbatim]
17 20
18 class Option; 21 class Option;
19 class App; 22 class App;
@@ -177,4 +180,5 @@ class Formatter : public FormatterBase { @@ -177,4 +180,5 @@ class Formatter : public FormatterBase {
177 ///@} 180 ///@}
178 }; 181 };
179 182
  183 +// [CLI11:formatter_fwd_hpp:end]
180 } // namespace CLI 184 } // namespace CLI
include/CLI/Macros.hpp
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 6
7 #pragma once 7 #pragma once
8 8
9 -// [CLI11:verbatim] 9 +// [CLI11:macros_hpp:verbatim]
10 10
11 // The following version macro is very similar to the one in PyBind11 11 // The following version macro is very similar to the one in PyBind11
12 #if !(defined(_MSC_VER) && __cplusplus == 199711L) && !defined(__INTEL_COMPILER) 12 #if !(defined(_MSC_VER) && __cplusplus == 199711L) && !defined(__INTEL_COMPILER)
@@ -41,4 +41,4 @@ @@ -41,4 +41,4 @@
41 #define CLI11_DEPRECATED(reason) __attribute__((deprecated(reason))) 41 #define CLI11_DEPRECATED(reason) __attribute__((deprecated(reason)))
42 #endif 42 #endif
43 43
44 -// [CLI11:verbatim] 44 +// [CLI11:macros_hpp:end]
include/CLI/Option.hpp
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 6
7 #pragma once 7 #pragma once
8 8
  9 +// [CLI11:public_includes:set]
9 #include <algorithm> 10 #include <algorithm>
10 #include <functional> 11 #include <functional>
11 #include <memory> 12 #include <memory>
@@ -14,6 +15,7 @@ @@ -14,6 +15,7 @@
14 #include <tuple> 15 #include <tuple>
15 #include <utility> 16 #include <utility>
16 #include <vector> 17 #include <vector>
  18 +// [CLI11:public_includes:end]
17 19
18 #include "Error.hpp" 20 #include "Error.hpp"
19 #include "Macros.hpp" 21 #include "Macros.hpp"
@@ -22,6 +24,7 @@ @@ -22,6 +24,7 @@
22 #include "Validators.hpp" 24 #include "Validators.hpp"
23 25
24 namespace CLI { 26 namespace CLI {
  27 +// [CLI11:option_hpp:verbatim]
25 28
26 using results_t = std::vector<std::string>; 29 using results_t = std::vector<std::string>;
27 /// callback function definition 30 /// callback function definition
@@ -1316,4 +1319,5 @@ class Option : public OptionBase&lt;Option&gt; { @@ -1316,4 +1319,5 @@ class Option : public OptionBase&lt;Option&gt; {
1316 } 1319 }
1317 }; // namespace CLI 1320 }; // namespace CLI
1318 1321
  1322 +// [CLI11:option_hpp:end]
1319 } // namespace CLI 1323 } // namespace CLI
include/CLI/Split.hpp
@@ -6,15 +6,19 @@ @@ -6,15 +6,19 @@
6 6
7 #pragma once 7 #pragma once
8 8
  9 +// [CLI11:public_includes:set]
9 #include <string> 10 #include <string>
10 #include <tuple> 11 #include <tuple>
11 #include <utility> 12 #include <utility>
12 #include <vector> 13 #include <vector>
  14 +// [CLI11:public_includes:end]
13 15
14 #include "Error.hpp" 16 #include "Error.hpp"
15 #include "StringTools.hpp" 17 #include "StringTools.hpp"
16 18
17 namespace CLI { 19 namespace CLI {
  20 +// [CLI11:split_hpp:verbatim]
  21 +
18 namespace detail { 22 namespace detail {
19 23
20 // Returns false if not a short option. Otherwise, sets opt name and rest and returns true 24 // Returns false if not a short option. Otherwise, sets opt name and rest and returns true
@@ -135,4 +139,5 @@ get_names(const std::vector&lt;std::string&gt; &amp;input) { @@ -135,4 +139,5 @@ get_names(const std::vector&lt;std::string&gt; &amp;input) {
135 } 139 }
136 140
137 } // namespace detail 141 } // namespace detail
  142 +// [CLI11:split_hpp:end]
138 } // namespace CLI 143 } // namespace CLI
include/CLI/StringTools.hpp
@@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
6 6
7 #pragma once 7 #pragma once
8 8
  9 +// [CLI11:public_includes:set]
9 #include <algorithm> 10 #include <algorithm>
10 #include <iomanip> 11 #include <iomanip>
11 #include <locale> 12 #include <locale>
@@ -14,9 +15,12 @@ @@ -14,9 +15,12 @@
14 #include <string> 15 #include <string>
15 #include <type_traits> 16 #include <type_traits>
16 #include <vector> 17 #include <vector>
  18 +// [CLI11:public_includes:end]
17 19
18 namespace CLI { 20 namespace CLI {
19 21
  22 +// [CLI11:string_tools_hpp:verbatim]
  23 +
20 /// Include the items in this namespace to get free conversion of enums to/from streams. 24 /// Include the items in this namespace to get free conversion of enums to/from streams.
21 /// (This is available inside CLI as well, so CLI11 will use this without a using statement). 25 /// (This is available inside CLI as well, so CLI11 will use this without a using statement).
22 namespace enums { 26 namespace enums {
@@ -409,4 +413,6 @@ inline std::string &amp;add_quotes_if_needed(std::string &amp;str) { @@ -409,4 +413,6 @@ inline std::string &amp;add_quotes_if_needed(std::string &amp;str) {
409 413
410 } // namespace detail 414 } // namespace detail
411 415
  416 +// [CLI11:string_tools_hpp:end]
  417 +
412 } // namespace CLI 418 } // namespace CLI
include/CLI/TypeTools.hpp
@@ -6,7 +6,7 @@ @@ -6,7 +6,7 @@
6 6
7 #pragma once 7 #pragma once
8 8
9 -#include "StringTools.hpp" 9 +// [CLI11:public_includes:set]
10 #include <cstdint> 10 #include <cstdint>
11 #include <exception> 11 #include <exception>
12 #include <memory> 12 #include <memory>
@@ -14,8 +14,12 @@ @@ -14,8 +14,12 @@
14 #include <type_traits> 14 #include <type_traits>
15 #include <utility> 15 #include <utility>
16 #include <vector> 16 #include <vector>
  17 +// [CLI11:public_includes:end]
  18 +
  19 +#include "StringTools.hpp"
17 20
18 namespace CLI { 21 namespace CLI {
  22 +// [CLI11:type_tools_hpp:verbatim]
19 23
20 // Type tools 24 // Type tools
21 25
@@ -1540,4 +1544,5 @@ void sum_flag_vector(const std::vector&lt;std::string&gt; &amp;flags, T &amp;output) { @@ -1540,4 +1544,5 @@ void sum_flag_vector(const std::vector&lt;std::string&gt; &amp;flags, T &amp;output) {
1540 #endif 1544 #endif
1541 1545
1542 } // namespace detail 1546 } // namespace detail
  1547 +// [CLI11:type_tools_hpp:end]
1543 } // namespace CLI 1548 } // namespace CLI
include/CLI/Validators.hpp
@@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
10 #include "StringTools.hpp" 10 #include "StringTools.hpp"
11 #include "TypeTools.hpp" 11 #include "TypeTools.hpp"
12 12
  13 +// [CLI11:public_includes:set]
13 #include <cmath> 14 #include <cmath>
14 #include <cstdint> 15 #include <cstdint>
15 #include <functional> 16 #include <functional>
@@ -20,8 +21,9 @@ @@ -20,8 +21,9 @@
20 #include <string> 21 #include <string>
21 #include <utility> 22 #include <utility>
22 #include <vector> 23 #include <vector>
  24 +// [CLI11:public_includes:end]
23 25
24 -// [CLI11:verbatim] 26 +// [CLI11:validators_hpp_filesystem:verbatim]
25 27
26 // C standard library 28 // C standard library
27 // Only needed for existence checking 29 // Only needed for existence checking
@@ -55,9 +57,10 @@ @@ -55,9 +57,10 @@
55 #include <sys/types.h> 57 #include <sys/types.h>
56 #endif 58 #endif
57 59
58 -// [CLI11:verbatim] 60 +// [CLI11:validators_hpp_filesystem:end]
59 61
60 namespace CLI { 62 namespace CLI {
  63 +// [CLI11:validators_hpp:verbatim]
61 64
62 class Option; 65 class Option;
63 66
@@ -1112,4 +1115,5 @@ inline std::pair&lt;std::string, std::string&gt; split_program_name(std::string comman @@ -1112,4 +1115,5 @@ inline std::pair&lt;std::string, std::string&gt; split_program_name(std::string comman
1112 } // namespace detail 1115 } // namespace detail
1113 /// @} 1116 /// @}
1114 1117
  1118 +// [CLI11:validators_hpp:end]
1115 } // namespace CLI 1119 } // namespace CLI
include/CLI/Version.hpp
@@ -6,11 +6,11 @@ @@ -6,11 +6,11 @@
6 6
7 #pragma once 7 #pragma once
8 8
9 -// [CLI11:verbatim] 9 +// [CLI11:version_hpp:verbatim]
10 10
11 #define CLI11_VERSION_MAJOR 1 11 #define CLI11_VERSION_MAJOR 1
12 #define CLI11_VERSION_MINOR 9 12 #define CLI11_VERSION_MINOR 9
13 #define CLI11_VERSION_PATCH 1 13 #define CLI11_VERSION_PATCH 1
14 #define CLI11_VERSION "1.9.1" 14 #define CLI11_VERSION "1.9.1"
15 15
16 -// [CLI11:verbatim] 16 +// [CLI11:version_hpp:end]
scripts/MakeSingleHeader.py
@@ -5,171 +5,136 @@ from __future__ import print_function, unicode_literals @@ -5,171 +5,136 @@ from __future__ import print_function, unicode_literals
5 import os 5 import os
6 import re 6 import re
7 from argparse import ArgumentParser 7 from argparse import ArgumentParser
8 -from operator import add  
9 -from copy import copy  
10 -from functools import reduce  
11 from subprocess import Popen, PIPE 8 from subprocess import Popen, PIPE
12 -  
13 -includes_local = re.compile(r"""^#include "(.*)"$""", re.MULTILINE)  
14 -includes_system = re.compile(r"""^#include \<(.*)\>$""", re.MULTILINE)  
15 -version_finder = re.compile(r"""^#define CLI11_VERSION \"(.*)\"$""", re.MULTILINE)  
16 -verbatim_tag_str = r"""  
17 -^ # Begin of line  
18 -[^\n^\[]+ # Some characters, not including [ or the end of a line  
19 -\[ # A literal [  
20 -[^\]^\n]* # Anything except a closing ]  
21 -CLI11:verbatim # The tag  
22 -[^\]^\n]* # Anything except a closing ]  
23 -\] # A literal ]  
24 -[^\n]* # Up to end of line  
25 -$ # End of a line 9 +import warnings
  10 +
  11 +tag_str = r"""
  12 +^ # Begin of line
  13 +[/\s]+ # Whitespace or comment // chars
  14 +\[ # A literal [
  15 +{tag}: # The tag
  16 +(?P<name>[\w_]+) # name: group name
  17 +: # Colon
  18 +(?P<action>[\w_]+) # action: type of include
  19 +\] # A literal ]
  20 +\s* # Whitespace
  21 +$ # End of a line
  22 +
  23 +(?P<content>.*) # All
  24 +
  25 +^ # Begin of line
  26 +[/\s]+ # Whitespace or comment // chars
  27 +\[ # A literal [
  28 +{tag}: # The tag
  29 +(?P=name) # Repeated name
  30 +: # Colon
  31 +end # Literal "end"
  32 +\] # A literal ]
  33 +\s* # Whitespace
  34 +$ # End of a line
26 """ 35 """
27 -verbatim_all = re.compile(  
28 - verbatim_tag_str + "(.*)" + verbatim_tag_str, re.MULTILINE | re.DOTALL | re.VERBOSE  
29 -)  
30 36
31 DIR = os.path.dirname(os.path.abspath(__file__)) 37 DIR = os.path.dirname(os.path.abspath(__file__))
32 38
33 39
34 -class HeaderFile(object):  
35 - TAG = "Unknown git revision"  
36 - LICENSE = "// BSD 3 clause"  
37 - VERSION = "Unknown" 40 +class HeaderGroups(dict):
  41 + def __init__(self, tag):
  42 + self.re_matcher = re.compile(
  43 + tag_str.format(tag=tag), re.MULTILINE | re.DOTALL | re.VERBOSE
  44 + )
  45 + super(HeaderGroups, self).__init__()
38 46
39 - def __init__(self, base, inc):  
40 - with open(os.path.join(base, inc)) as f: 47 + def read_header(self, filename):
  48 + with open(filename) as f:
41 inner = f.read() 49 inner = f.read()
42 50
43 - version = version_finder.search(inner)  
44 - if version:  
45 - self.__class__.VERSION = version.groups()[0]  
46 -  
47 - # add self.verbatim  
48 - if "CLI11:verbatim" in inner:  
49 - self.verbatim = ["\n\n// Verbatim copy from {0}:".format(inc)]  
50 - self.verbatim += verbatim_all.findall(inner)  
51 - inner = verbatim_all.sub("", inner)  
52 - else:  
53 - self.verbatim = []  
54 -  
55 - self.headers = set(includes_system.findall(inner))  
56 -  
57 - self.body = "\n// From {0}:\n\n".format(inc) + inner[inner.find("namespace") :]  
58 -  
59 - self.namespace = None  
60 -  
61 - def __add__(self, other):  
62 - out = copy(self)  
63 - out.headers |= other.headers  
64 - out.body += other.body  
65 - out.verbatim += other.verbatim  
66 - return out  
67 -  
68 - @property  
69 - def header_str(self):  
70 - return "\n".join("#include <" + h + ">" for h in sorted(self.headers))  
71 -  
72 - @property  
73 - def verbatim_str(self):  
74 - return "\n".join(self.verbatim)  
75 -  
76 - def insert_namespace(self, namespace):  
77 - self.namespace = namespace  
78 -  
79 - def macro_replacement(self, before, after):  
80 - self.verbatim = [x.replace(before, after) for x in self.verbatim]  
81 - self.body = self.body.replace(before, after)  
82 -  
83 - def __str__(self):  
84 - result = """\  
85 -#pragma once  
86 -  
87 -// CLI11: Version {self.VERSION}  
88 -// Originally designed by Henry Schreiner  
89 -// https://github.com/CLIUtils/CLI11  
90 -//  
91 -// This is a standalone header file generated by MakeSingleHeader.py in CLI11/scripts  
92 -// from: {self.TAG}  
93 -//  
94 -// From LICENSE:  
95 -//  
96 -{self.LICENSE}  
97 -  
98 -// Standard combined includes:  
99 -  
100 -{self.header_str}  
101 -""".format(  
102 - self=self  
103 - ) 51 + matches = self.re_matcher.findall(inner)
  52 +
  53 + if not matches:
  54 + warnings.warn(
  55 + "Failed to find any matches in {filename}".format(filename=filename)
  56 + )
104 57
105 - if self.namespace:  
106 - result += "\nnamespace " + self.namespace + " {\n\n"  
107 - result += "{self.verbatim_str}\n{self.body}\n".format(self=self)  
108 - if self.namespace:  
109 - result += "} // namespace " + self.namespace + "\n\n" 58 + for name, action, content in matches:
  59 + if action == "verbatim":
  60 + assert (
  61 + name not in self
  62 + ), "{name} read in more than once! Quitting.".format(name=name)
  63 + self[name] = content
  64 + elif action == "set":
  65 + self[name] = self.get(name, set()) | set(content.strip().splitlines())
  66 + else:
  67 + raise RuntimeError("Action not understood, must be verbatim or set")
110 68
111 - return result 69 + def post_process(self):
  70 + for key in self:
  71 + if isinstance(self[key], set):
  72 + self[key] = "\n".join(self[key])
112 73
113 74
114 -def MakeHeader(  
115 - output, main_header, include_dir="../include", namespace=None, macro=None  
116 -): 75 +def MakeHeader(output, main_header, files, tag, namespace, macro=None, version=None):
  76 + groups = HeaderGroups(tag)
  77 +
117 # Set tag if possible to class variable 78 # Set tag if possible to class variable
118 try: 79 try:
119 proc = Popen( 80 proc = Popen(
120 ["git", "describe", "--tags", "--always"], cwd=str(DIR), stdout=PIPE 81 ["git", "describe", "--tags", "--always"], cwd=str(DIR), stdout=PIPE
121 ) 82 )
122 out, _ = proc.communicate() 83 out, _ = proc.communicate()
  84 + groups["git"] = out.decode("utf-8").strip() if proc.returncode == 0 else ""
123 except OSError: 85 except OSError:
124 - pass  
125 - else:  
126 - if proc.returncode == 0:  
127 - HeaderFile.TAG = out.decode("utf-8").strip()  
128 -  
129 - base_dir = os.path.abspath(os.path.join(DIR, include_dir))  
130 - main_header = os.path.join(base_dir, main_header)  
131 - header_dir = os.path.dirname(main_header)  
132 - licence_file = os.path.abspath(os.path.join(DIR, "../LICENSE")) 86 + groups["git"] = ""
133 87
134 - with open(licence_file) as f:  
135 - HeaderFile.LICENSE = "".join("// " + line for line in f) 88 + for f in files:
  89 + groups.read_header(f)
136 90
137 - with open(main_header) as f:  
138 - header = f.read() 91 + groups["namespace"] = namespace
  92 + groups["version"] = version or groups["git"]
139 93
140 - include_files = includes_local.findall(header) 94 + groups.post_process()
141 95
142 - headers = [HeaderFile(header_dir, inc) for inc in include_files]  
143 - single_header = reduce(add, headers) 96 + with open(main_header) as f:
  97 + single_header = f.read().format(**groups)
144 98
145 if macro is not None: 99 if macro is not None:
146 - before = "CLI11_"  
147 - print("Converting macros", before, "->", macro)  
148 - single_header.macro_replacement(before, macro) 100 + before, after = macro
  101 + print("Converting macros", before, "->", after)
  102 + single_header.replace(before, after)
149 103
150 - if namespace:  
151 - print("Adding namespace", namespace)  
152 - single_header.insert_namespace(namespace) 104 + if output is not None:
  105 + with open(output, "w") as f:
  106 + f.write(single_header)
153 107
154 - with open(output, "w") as f:  
155 - f.write(str(single_header))  
156 -  
157 - print("Created", output) 108 + print("Created", output)
  109 + else:
  110 + print(single_header)
158 111
159 112
160 if __name__ == "__main__": 113 if __name__ == "__main__":
161 parser = ArgumentParser( 114 parser = ArgumentParser(
162 usage="Convert source to single header include. Can optionally add namespace and search-replace replacements (for macros)." 115 usage="Convert source to single header include. Can optionally add namespace and search-replace replacements (for macros)."
163 ) 116 )
164 - parser.add_argument("output", help="Single header file output") 117 + parser.add_argument("--output", default=None, help="Single header file output")
165 parser.add_argument( 118 parser.add_argument(
166 "--main", 119 "--main",
167 - default="CLI/CLI.hpp", 120 + default="CLI11.hpp.in",
168 help="The main include file that defines the other files", 121 help="The main include file that defines the other files",
169 ) 122 )
170 - parser.add_argument("--include", default="../include", help="The include directory")  
171 - parser.add_argument("--namespace", help="Add an optional namespace")  
172 - parser.add_argument("--macro", help="Replaces CLI11_ with NEW_PREFIX_") 123 + parser.add_argument("files", nargs="*", help="The header files")
  124 + parser.add_argument("--namespace", default="CLI", help="Set the namespace")
  125 + parser.add_argument("--tag", default="CLI11", help="Tag to look up")
  126 + parser.add_argument(
  127 + "--macro", nargs=2, help="Replaces OLD_PREFIX_ with NEW_PREFIX_"
  128 + )
  129 + parser.add_argument("--version", help="Include this version in the generated file")
173 args = parser.parse_args() 130 args = parser.parse_args()
174 131
175 - MakeHeader(args.output, args.main, args.include, args.namespace, args.macro) 132 + MakeHeader(
  133 + args.output,
  134 + args.main,
  135 + args.files,
  136 + args.tag,
  137 + args.namespace,
  138 + args.macro,
  139 + args.version,
  140 + )