You need to sign in before continuing.
Commit f862849488557eeee0397814a47449ecfdae0383
Committed by
GitHub
1 parent
32e6c3f3
refactor: new version of MakeSingleFiles (#546)
* refactor: new version of MakeSingleFiles * fix: use CMake and set version
Showing
17 changed files
with
224 additions
and
142 deletions
.github/workflows/build.yml
| ... | ... | @@ -22,11 +22,8 @@ jobs: |
| 22 | 22 | |
| 23 | 23 | - uses: actions/setup-python@v2 |
| 24 | 24 | |
| 25 | - - name: Make header | |
| 26 | - run: python ./scripts/MakeSingleHeader.py CLI11.hpp | |
| 27 | - | |
| 28 | 25 | - name: Prepare CMake config |
| 29 | - run: cmake -S . -B build | |
| 26 | + run: cmake -S . -B build -DCLI11_SINGLE_FILE=ON | |
| 30 | 27 | |
| 31 | 28 | - name: Make package |
| 32 | 29 | run: cmake --build build --target package_source |
| ... | ... | @@ -37,10 +34,13 @@ jobs: |
| 37 | 34 | cp build/CLI11-*-Source.* CLI11-Source |
| 38 | 35 | cp build/CLI11-*-Source.* . |
| 39 | 36 | |
| 37 | + - name: Make header | |
| 38 | + run: cmake --build build --target CLI11-generate-single-file | |
| 39 | + | |
| 40 | 40 | - uses: actions/upload-artifact@v2 |
| 41 | 41 | with: |
| 42 | 42 | name: CLI11.hpp |
| 43 | - path: CLI11.hpp | |
| 43 | + path: build/include/CLI11.hpp | |
| 44 | 44 | |
| 45 | 45 | - uses: actions/upload-artifact@v2 |
| 46 | 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 | 247 | add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/CLI11.hpp" |
| 248 | 248 | COMMAND Python::Interpreter |
| 249 | 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 | 254 | DEPENDS |
| 252 | 255 | "${CMAKE_CURRENT_SOURCE_DIR}/include/CLI/CLI.hpp" |
| 253 | 256 | ${CLI11_headers}) | ... | ... |
include/CLI/App.hpp
| ... | ... | @@ -6,6 +6,7 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | +// [CLI11:public_includes:set] | |
| 9 | 10 | #include <algorithm> |
| 10 | 11 | #include <cstdint> |
| 11 | 12 | #include <functional> |
| ... | ... | @@ -18,6 +19,7 @@ |
| 18 | 19 | #include <string> |
| 19 | 20 | #include <utility> |
| 20 | 21 | #include <vector> |
| 22 | +// [CLI11:public_includes:end] | |
| 21 | 23 | |
| 22 | 24 | // CLI Library includes |
| 23 | 25 | #include "ConfigFwd.hpp" |
| ... | ... | @@ -30,6 +32,7 @@ |
| 30 | 32 | #include "TypeTools.hpp" |
| 31 | 33 | |
| 32 | 34 | namespace CLI { |
| 35 | +// [CLI11:app_hpp:verbatim] | |
| 33 | 36 | |
| 34 | 37 | #ifndef CLI11_PARSE |
| 35 | 38 | #define CLI11_PARSE(app, argc, argv) \ |
| ... | ... | @@ -3234,4 +3237,5 @@ struct AppFriend { |
| 3234 | 3237 | }; |
| 3235 | 3238 | } // namespace detail |
| 3236 | 3239 | |
| 3240 | +// [CLI11:app_hpp:end] | |
| 3237 | 3241 | } // namespace CLI | ... | ... |
include/CLI/Config.hpp
| ... | ... | @@ -6,19 +6,21 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | +// [CLI11:public_includes:set] | |
| 9 | 10 | #include <algorithm> |
| 10 | 11 | #include <fstream> |
| 11 | 12 | #include <iostream> |
| 12 | 13 | #include <string> |
| 13 | 14 | #include <utility> |
| 14 | 15 | #include <vector> |
| 16 | +// [CLI11:public_includes:set] | |
| 15 | 17 | |
| 16 | 18 | #include "App.hpp" |
| 17 | 19 | #include "ConfigFwd.hpp" |
| 18 | 20 | #include "StringTools.hpp" |
| 19 | 21 | |
| 20 | 22 | namespace CLI { |
| 21 | - | |
| 23 | +// [CLI11:config_hpp:verbatim] | |
| 22 | 24 | namespace detail { |
| 23 | 25 | |
| 24 | 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 | 350 | return out.str(); |
| 349 | 351 | } |
| 350 | 352 | |
| 353 | +// [CLI11:config_hpp:end] | |
| 351 | 354 | } // namespace CLI | ... | ... |
include/CLI/ConfigFwd.hpp
| ... | ... | @@ -6,16 +6,19 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | +// [CLI11:public_includes:set] | |
| 9 | 10 | #include <algorithm> |
| 10 | 11 | #include <fstream> |
| 11 | 12 | #include <iostream> |
| 12 | 13 | #include <string> |
| 13 | 14 | #include <vector> |
| 15 | +// [CLI11:public_includes:end] | |
| 14 | 16 | |
| 15 | 17 | #include "Error.hpp" |
| 16 | 18 | #include "StringTools.hpp" |
| 17 | 19 | |
| 18 | 20 | namespace CLI { |
| 21 | +// [CLI11:config_fwd_hpp:verbatim] | |
| 19 | 22 | |
| 20 | 23 | class App; |
| 21 | 24 | |
| ... | ... | @@ -128,4 +131,5 @@ class ConfigINI : public ConfigTOML { |
| 128 | 131 | valueDelimiter = '='; |
| 129 | 132 | } |
| 130 | 133 | }; |
| 134 | +// [CLI11:config_fwd_hpp:end] | |
| 131 | 135 | } // namespace CLI | ... | ... |
include/CLI/Error.hpp
| ... | ... | @@ -6,16 +6,19 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | +// [CLI11:public_includes:set] | |
| 9 | 10 | #include <exception> |
| 10 | 11 | #include <stdexcept> |
| 11 | 12 | #include <string> |
| 12 | 13 | #include <utility> |
| 13 | 14 | #include <vector> |
| 15 | +// [CLI11:public_includes:end] | |
| 14 | 16 | |
| 15 | 17 | // CLI library includes |
| 16 | 18 | #include "StringTools.hpp" |
| 17 | 19 | |
| 18 | 20 | namespace CLI { |
| 21 | +// [CLI11:error_hpp:verbatim] | |
| 19 | 22 | |
| 20 | 23 | // Use one of these on all error classes. |
| 21 | 24 | // These are temporary and are undef'd at the end of this file. |
| ... | ... | @@ -344,4 +347,5 @@ class OptionNotFound : public Error { |
| 344 | 347 | |
| 345 | 348 | /// @} |
| 346 | 349 | |
| 350 | +// [CLI11:error_hpp:end] | |
| 347 | 351 | } // namespace CLI | ... | ... |
include/CLI/Formatter.hpp
| ... | ... | @@ -6,14 +6,17 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | +// [CLI11:public_includes:set] | |
| 9 | 10 | #include <algorithm> |
| 10 | 11 | #include <string> |
| 11 | 12 | #include <vector> |
| 13 | +// [CLI11:public_includes:end] | |
| 12 | 14 | |
| 13 | 15 | #include "App.hpp" |
| 14 | 16 | #include "FormatterFwd.hpp" |
| 15 | 17 | |
| 16 | 18 | namespace CLI { |
| 19 | +// [CLI11:formatter_hpp:verbatim] | |
| 17 | 20 | |
| 18 | 21 | inline std::string |
| 19 | 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 | 288 | return opt->get_required() ? out.str() : "[" + out.str() + "]"; |
| 286 | 289 | } |
| 287 | 290 | |
| 291 | +// [CLI11:formatter_hpp:end] | |
| 288 | 292 | } // namespace CLI | ... | ... |
include/CLI/FormatterFwd.hpp
| ... | ... | @@ -6,14 +6,17 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | +// [CLI11:public_includes:set] | |
| 9 | 10 | #include <map> |
| 10 | 11 | #include <string> |
| 11 | 12 | #include <utility> |
| 12 | 13 | #include <vector> |
| 14 | +// [CLI11:public_includes:end] | |
| 13 | 15 | |
| 14 | 16 | #include "StringTools.hpp" |
| 15 | 17 | |
| 16 | 18 | namespace CLI { |
| 19 | +// [CLI11:formatter_fwd_hpp:verbatim] | |
| 17 | 20 | |
| 18 | 21 | class Option; |
| 19 | 22 | class App; |
| ... | ... | @@ -177,4 +180,5 @@ class Formatter : public FormatterBase { |
| 177 | 180 | ///@} |
| 178 | 181 | }; |
| 179 | 182 | |
| 183 | +// [CLI11:formatter_fwd_hpp:end] | |
| 180 | 184 | } // namespace CLI | ... | ... |
include/CLI/Macros.hpp
| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | -// [CLI11:verbatim] | |
| 9 | +// [CLI11:macros_hpp:verbatim] | |
| 10 | 10 | |
| 11 | 11 | // The following version macro is very similar to the one in PyBind11 |
| 12 | 12 | #if !(defined(_MSC_VER) && __cplusplus == 199711L) && !defined(__INTEL_COMPILER) |
| ... | ... | @@ -41,4 +41,4 @@ |
| 41 | 41 | #define CLI11_DEPRECATED(reason) __attribute__((deprecated(reason))) |
| 42 | 42 | #endif |
| 43 | 43 | |
| 44 | -// [CLI11:verbatim] | |
| 44 | +// [CLI11:macros_hpp:end] | ... | ... |
include/CLI/Option.hpp
| ... | ... | @@ -6,6 +6,7 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | +// [CLI11:public_includes:set] | |
| 9 | 10 | #include <algorithm> |
| 10 | 11 | #include <functional> |
| 11 | 12 | #include <memory> |
| ... | ... | @@ -14,6 +15,7 @@ |
| 14 | 15 | #include <tuple> |
| 15 | 16 | #include <utility> |
| 16 | 17 | #include <vector> |
| 18 | +// [CLI11:public_includes:end] | |
| 17 | 19 | |
| 18 | 20 | #include "Error.hpp" |
| 19 | 21 | #include "Macros.hpp" |
| ... | ... | @@ -22,6 +24,7 @@ |
| 22 | 24 | #include "Validators.hpp" |
| 23 | 25 | |
| 24 | 26 | namespace CLI { |
| 27 | +// [CLI11:option_hpp:verbatim] | |
| 25 | 28 | |
| 26 | 29 | using results_t = std::vector<std::string>; |
| 27 | 30 | /// callback function definition |
| ... | ... | @@ -1316,4 +1319,5 @@ class Option : public OptionBase<Option> { |
| 1316 | 1319 | } |
| 1317 | 1320 | }; // namespace CLI |
| 1318 | 1321 | |
| 1322 | +// [CLI11:option_hpp:end] | |
| 1319 | 1323 | } // namespace CLI | ... | ... |
include/CLI/Split.hpp
| ... | ... | @@ -6,15 +6,19 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | +// [CLI11:public_includes:set] | |
| 9 | 10 | #include <string> |
| 10 | 11 | #include <tuple> |
| 11 | 12 | #include <utility> |
| 12 | 13 | #include <vector> |
| 14 | +// [CLI11:public_includes:end] | |
| 13 | 15 | |
| 14 | 16 | #include "Error.hpp" |
| 15 | 17 | #include "StringTools.hpp" |
| 16 | 18 | |
| 17 | 19 | namespace CLI { |
| 20 | +// [CLI11:split_hpp:verbatim] | |
| 21 | + | |
| 18 | 22 | namespace detail { |
| 19 | 23 | |
| 20 | 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<std::string> &input) { |
| 135 | 139 | } |
| 136 | 140 | |
| 137 | 141 | } // namespace detail |
| 142 | +// [CLI11:split_hpp:end] | |
| 138 | 143 | } // namespace CLI | ... | ... |
include/CLI/StringTools.hpp
| ... | ... | @@ -6,6 +6,7 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | +// [CLI11:public_includes:set] | |
| 9 | 10 | #include <algorithm> |
| 10 | 11 | #include <iomanip> |
| 11 | 12 | #include <locale> |
| ... | ... | @@ -14,9 +15,12 @@ |
| 14 | 15 | #include <string> |
| 15 | 16 | #include <type_traits> |
| 16 | 17 | #include <vector> |
| 18 | +// [CLI11:public_includes:end] | |
| 17 | 19 | |
| 18 | 20 | namespace CLI { |
| 19 | 21 | |
| 22 | +// [CLI11:string_tools_hpp:verbatim] | |
| 23 | + | |
| 20 | 24 | /// Include the items in this namespace to get free conversion of enums to/from streams. |
| 21 | 25 | /// (This is available inside CLI as well, so CLI11 will use this without a using statement). |
| 22 | 26 | namespace enums { |
| ... | ... | @@ -409,4 +413,6 @@ inline std::string &add_quotes_if_needed(std::string &str) { |
| 409 | 413 | |
| 410 | 414 | } // namespace detail |
| 411 | 415 | |
| 416 | +// [CLI11:string_tools_hpp:end] | |
| 417 | + | |
| 412 | 418 | } // namespace CLI | ... | ... |
include/CLI/TypeTools.hpp
| ... | ... | @@ -6,7 +6,7 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | -#include "StringTools.hpp" | |
| 9 | +// [CLI11:public_includes:set] | |
| 10 | 10 | #include <cstdint> |
| 11 | 11 | #include <exception> |
| 12 | 12 | #include <memory> |
| ... | ... | @@ -14,8 +14,12 @@ |
| 14 | 14 | #include <type_traits> |
| 15 | 15 | #include <utility> |
| 16 | 16 | #include <vector> |
| 17 | +// [CLI11:public_includes:end] | |
| 18 | + | |
| 19 | +#include "StringTools.hpp" | |
| 17 | 20 | |
| 18 | 21 | namespace CLI { |
| 22 | +// [CLI11:type_tools_hpp:verbatim] | |
| 19 | 23 | |
| 20 | 24 | // Type tools |
| 21 | 25 | |
| ... | ... | @@ -1540,4 +1544,5 @@ void sum_flag_vector(const std::vector<std::string> &flags, T &output) { |
| 1540 | 1544 | #endif |
| 1541 | 1545 | |
| 1542 | 1546 | } // namespace detail |
| 1547 | +// [CLI11:type_tools_hpp:end] | |
| 1543 | 1548 | } // namespace CLI | ... | ... |
include/CLI/Validators.hpp
| ... | ... | @@ -10,6 +10,7 @@ |
| 10 | 10 | #include "StringTools.hpp" |
| 11 | 11 | #include "TypeTools.hpp" |
| 12 | 12 | |
| 13 | +// [CLI11:public_includes:set] | |
| 13 | 14 | #include <cmath> |
| 14 | 15 | #include <cstdint> |
| 15 | 16 | #include <functional> |
| ... | ... | @@ -20,8 +21,9 @@ |
| 20 | 21 | #include <string> |
| 21 | 22 | #include <utility> |
| 22 | 23 | #include <vector> |
| 24 | +// [CLI11:public_includes:end] | |
| 23 | 25 | |
| 24 | -// [CLI11:verbatim] | |
| 26 | +// [CLI11:validators_hpp_filesystem:verbatim] | |
| 25 | 27 | |
| 26 | 28 | // C standard library |
| 27 | 29 | // Only needed for existence checking |
| ... | ... | @@ -55,9 +57,10 @@ |
| 55 | 57 | #include <sys/types.h> |
| 56 | 58 | #endif |
| 57 | 59 | |
| 58 | -// [CLI11:verbatim] | |
| 60 | +// [CLI11:validators_hpp_filesystem:end] | |
| 59 | 61 | |
| 60 | 62 | namespace CLI { |
| 63 | +// [CLI11:validators_hpp:verbatim] | |
| 61 | 64 | |
| 62 | 65 | class Option; |
| 63 | 66 | |
| ... | ... | @@ -1112,4 +1115,5 @@ inline std::pair<std::string, std::string> split_program_name(std::string comman |
| 1112 | 1115 | } // namespace detail |
| 1113 | 1116 | /// @} |
| 1114 | 1117 | |
| 1118 | +// [CLI11:validators_hpp:end] | |
| 1115 | 1119 | } // namespace CLI | ... | ... |
include/CLI/Version.hpp
| ... | ... | @@ -6,11 +6,11 @@ |
| 6 | 6 | |
| 7 | 7 | #pragma once |
| 8 | 8 | |
| 9 | -// [CLI11:verbatim] | |
| 9 | +// [CLI11:version_hpp:verbatim] | |
| 10 | 10 | |
| 11 | 11 | #define CLI11_VERSION_MAJOR 1 |
| 12 | 12 | #define CLI11_VERSION_MINOR 9 |
| 13 | 13 | #define CLI11_VERSION_PATCH 1 |
| 14 | 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 | 5 | import os |
| 6 | 6 | import re |
| 7 | 7 | from argparse import ArgumentParser |
| 8 | -from operator import add | |
| 9 | -from copy import copy | |
| 10 | -from functools import reduce | |
| 11 | 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 | 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 | 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 | 78 | # Set tag if possible to class variable |
| 118 | 79 | try: |
| 119 | 80 | proc = Popen( |
| 120 | 81 | ["git", "describe", "--tags", "--always"], cwd=str(DIR), stdout=PIPE |
| 121 | 82 | ) |
| 122 | 83 | out, _ = proc.communicate() |
| 84 | + groups["git"] = out.decode("utf-8").strip() if proc.returncode == 0 else "" | |
| 123 | 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 | 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 | 113 | if __name__ == "__main__": |
| 161 | 114 | parser = ArgumentParser( |
| 162 | 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 | 118 | parser.add_argument( |
| 166 | 119 | "--main", |
| 167 | - default="CLI/CLI.hpp", | |
| 120 | + default="CLI11.hpp.in", | |
| 168 | 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 | 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 | + ) | ... | ... |