Commit d046fe0ad6acab5dbe0dcbc9457cad8fada8b288

Authored by Stefan Hillmich
Committed by GitHub
1 parent 82ac0838

Extend CI and small fixes (#370)

* Extend CI to support Windows and MacOS.
* Minor fixes to types.
.github/workflows/cmake.yml
@@ -2,43 +2,70 @@ name: CMake @@ -2,43 +2,70 @@ name: CMake
2 2
3 on: 3 on:
4 push: 4 push:
5 - branches: [ master ] 5 + branches: [ master, main ]
6 pull_request: 6 pull_request:
7 - branches: [ master ] 7 + branches: [ master, main ]
8 workflow_dispatch: 8 workflow_dispatch:
9 9
10 env: 10 env:
11 # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) 11 # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
12 BUILD_TYPE: Release 12 BUILD_TYPE: Release
13 13
  14 +
  15 +defaults:
  16 + run:
  17 + shell: bash
  18 +
14 jobs: 19 jobs:
15 - build:  
16 - # The CMake configure and build commands are platform agnostic and should work equally  
17 - # well on Windows or Mac. You can convert this to a matrix build if you need  
18 - # cross-platform coverage.  
19 - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix 20 + build-ubuntu:
  21 + strategy:
  22 + matrix:
  23 + os: [ ubuntu-18.04, ubuntu-20.04, ubuntu-22.04 ]
  24 + compiler: [ g++-9, g++-10, clang++ ]
  25 + include:
  26 + - os: ubuntu-18.04
  27 + compiler: g++-7
  28 + name: Build and Test on Ubuntu
20 runs-on: ${{matrix.os}} 29 runs-on: ${{matrix.os}}
  30 + steps:
  31 + - uses: actions/checkout@v3
  32 + - name: Configure CMake
  33 + run: cmake -S "${{github.workspace}}" -B "${{github.workspace}}/build" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_COMPILER=${{matrix.compiler}}
  34 + - name: Build
  35 + run: cmake --build "${{github.workspace}}/build" --config $BUILD_TYPE
  36 + - name: Test
  37 + working-directory: ${{github.workspace}}/build/test
  38 + run: ctest -C $BUILD_TYPE --output-on-failure
21 39
  40 + build-macos:
  41 + name: Build and Test on MacOS
22 strategy: 42 strategy:
23 matrix: 43 matrix:
24 - os: [ubuntu-18.04]  
25 - compiler: [g++-7, g++-9, g++-10, clang++]  
26 - 44 + os: [ macos-11, macos-12 ]
  45 + runs-on: ${{matrix.os}}
27 steps: 46 steps:
28 - - uses: actions/checkout@v2  
29 -  
30 - - name: Configure CMake  
31 - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.  
32 - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type  
33 - run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_CXX_COMPILER=${{matrix.compiler}} 47 + - uses: actions/checkout@v3
  48 + - name: Configure CMake
  49 + run: cmake -S "${{github.workspace}}" -B "${{github.workspace}}/build" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
  50 + - name: Show compile commands
  51 + run: cat build/compile_commands.json
  52 + - name: Build
  53 + run: cmake --build "${{github.workspace}}/build" --config $BUILD_TYPE
  54 + - name: Test
  55 + working-directory: ${{github.workspace}}/build/test
  56 + shell: bash
  57 + run: ctest -C $BUILD_TYPE --output-on-failure
34 58
35 - - name: Build  
36 - # Build your program with the given configuration  
37 - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}  
38 -  
39 - - name: Test  
40 - working-directory: ${{github.workspace}}/build  
41 - # Execute tests defined by the CMake configuration.  
42 - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail  
43 - run: ctest -C ${{env.BUILD_TYPE}}  
44 - 59 + build-windows:
  60 + name: Build and Test on Windows
  61 + runs-on: windows-latest
  62 + steps:
  63 + - uses: actions/checkout@v3
  64 + - uses: ilammy/msvc-dev-cmd@v1
  65 + - name: Configure CMake
  66 + run: cmake -S "${{github.workspace}}" -B "${{github.workspace}}/build" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -T "ClangCl"
  67 + - name: Build
  68 + run: cmake --build "${{github.workspace}}/build" --config $BUILD_TYPE
  69 + - name: Test
  70 + working-directory: ${{github.workspace}}/build/test
  71 + run: cd $BUILD_TYPE && ./link_test && ./options_test
include/cxxopts.hpp
@@ -27,13 +27,10 @@ THE SOFTWARE. @@ -27,13 +27,10 @@ THE SOFTWARE.
27 #ifndef CXXOPTS_HPP_INCLUDED 27 #ifndef CXXOPTS_HPP_INCLUDED
28 #define CXXOPTS_HPP_INCLUDED 28 #define CXXOPTS_HPP_INCLUDED
29 29
30 -#include <cassert>  
31 -#include <cctype>  
32 #include <cstring> 30 #include <cstring>
33 #include <exception> 31 #include <exception>
34 #include <limits> 32 #include <limits>
35 -#include <list>  
36 -#include <locale> 33 +#include <initializer_list>
37 #include <map> 34 #include <map>
38 #include <memory> 35 #include <memory>
39 #include <sstream> 36 #include <sstream>
@@ -196,9 +193,9 @@ stringAppend(String&amp;s, String a) @@ -196,9 +193,9 @@ stringAppend(String&amp;s, String a)
196 193
197 inline 194 inline
198 String& 195 String&
199 -stringAppend(String& s, size_t n, UChar32 c) 196 +stringAppend(String& s, std::size_t n, UChar32 c)
200 { 197 {
201 - for (size_t i = 0; i != n; ++i) 198 + for (std::size_t i = 0; i != n; ++i)
202 { 199 {
203 s.append(c); 200 s.append(c);
204 } 201 }
@@ -220,7 +217,7 @@ stringAppend(String&amp; s, Iterator begin, Iterator end) @@ -220,7 +217,7 @@ stringAppend(String&amp; s, Iterator begin, Iterator end)
220 } 217 }
221 218
222 inline 219 inline
223 -size_t 220 +std::size_t
224 stringLength(const String& s) 221 stringLength(const String& s)
225 { 222 {
226 return s.length(); 223 return s.length();
@@ -278,7 +275,7 @@ toLocalString(T&amp;&amp; t) @@ -278,7 +275,7 @@ toLocalString(T&amp;&amp; t)
278 } 275 }
279 276
280 inline 277 inline
281 -size_t 278 +std::size_t
282 stringLength(const String& s) 279 stringLength(const String& s)
283 { 280 {
284 return s.length(); 281 return s.length();
@@ -293,7 +290,7 @@ stringAppend(String&amp;s, const String&amp; a) @@ -293,7 +290,7 @@ stringAppend(String&amp;s, const String&amp; a)
293 290
294 inline 291 inline
295 String& 292 String&
296 -stringAppend(String& s, size_t n, char c) 293 +stringAppend(String& s, std::size_t n, char c)
297 { 294 {
298 return s.append(n, c); 295 return s.append(n, c);
299 } 296 }
@@ -682,7 +679,7 @@ inline OptionNames split_option_names(const std::string &amp;text) @@ -682,7 +679,7 @@ inline OptionNames split_option_names(const std::string &amp;text)
682 "abcdefghijklmnopqrstuvwxyz" 679 "abcdefghijklmnopqrstuvwxyz"
683 "0123456789" 680 "0123456789"
684 "_-"; 681 "_-";
685 - if (!std::isalnum(text[token_start_pos]) || 682 + if (!std::isalnum(text[token_start_pos], std::locale::classic()) ||
686 text.find_first_not_of(option_name_valid_chars, token_start_pos) < next_delimiter_pos) { 683 text.find_first_not_of(option_name_valid_chars, token_start_pos) < next_delimiter_pos) {
687 throw_or_mimic<exceptions::invalid_option_format>(text); 684 throw_or_mimic<exceptions::invalid_option_format>(text);
688 } 685 }
@@ -701,11 +698,11 @@ inline ArguDesc ParseArgument(const char *arg, bool &amp;matched) @@ -701,11 +698,11 @@ inline ArguDesc ParseArgument(const char *arg, bool &amp;matched)
701 if (strncmp(pdata, "--", 2) == 0) 698 if (strncmp(pdata, "--", 2) == 0)
702 { 699 {
703 pdata += 2; 700 pdata += 2;
704 - if (isalnum(*pdata)) 701 + if (isalnum(*pdata, std::locale::classic()))
705 { 702 {
706 argu_desc.arg_name.push_back(*pdata); 703 argu_desc.arg_name.push_back(*pdata);
707 pdata += 1; 704 pdata += 1;
708 - while (isalnum(*pdata) || *pdata == '-' || *pdata == '_') 705 + while (isalnum(*pdata, std::locale::classic()) || *pdata == '-' || *pdata == '_')
709 { 706 {
710 argu_desc.arg_name.push_back(*pdata); 707 argu_desc.arg_name.push_back(*pdata);
711 pdata += 1; 708 pdata += 1;
@@ -733,7 +730,7 @@ inline ArguDesc ParseArgument(const char *arg, bool &amp;matched) @@ -733,7 +730,7 @@ inline ArguDesc ParseArgument(const char *arg, bool &amp;matched)
733 { 730 {
734 pdata += 1; 731 pdata += 1;
735 argu_desc.grouping = true; 732 argu_desc.grouping = true;
736 - while (isalnum(*pdata)) 733 + while (isalnum(*pdata, std::locale::classic()))
737 { 734 {
738 argu_desc.arg_name.push_back(*pdata); 735 argu_desc.arg_name.push_back(*pdata);
739 pdata += 1; 736 pdata += 1;
@@ -1356,7 +1353,7 @@ class OptionDetails @@ -1356,7 +1353,7 @@ class OptionDetails
1356 return m_long; 1353 return m_long;
1357 } 1354 }
1358 1355
1359 - size_t 1356 + std::size_t
1360 hash() const 1357 hash() const
1361 { 1358 {
1362 return m_hash; 1359 return m_hash;
@@ -1369,7 +1366,7 @@ class OptionDetails @@ -1369,7 +1366,7 @@ class OptionDetails
1369 std::shared_ptr<const Value> m_value{}; 1366 std::shared_ptr<const Value> m_value{};
1370 int m_count; 1367 int m_count;
1371 1368
1372 - size_t m_hash{}; 1369 + std::size_t m_hash{};
1373 }; 1370 };
1374 1371
1375 struct HelpOptionDetails 1372 struct HelpOptionDetails
@@ -1430,7 +1427,7 @@ CXXOPTS_IGNORE_WARNING(&quot;-Wnull-dereference&quot;) @@ -1430,7 +1427,7 @@ CXXOPTS_IGNORE_WARNING(&quot;-Wnull-dereference&quot;)
1430 #endif 1427 #endif
1431 1428
1432 CXXOPTS_NODISCARD 1429 CXXOPTS_NODISCARD
1433 - size_t 1430 + std::size_t
1434 count() const noexcept 1431 count() const noexcept
1435 { 1432 {
1436 return m_count; 1433 return m_count;
@@ -1475,7 +1472,7 @@ CXXOPTS_DIAGNOSTIC_POP @@ -1475,7 +1472,7 @@ CXXOPTS_DIAGNOSTIC_POP
1475 // Holding this pointer is safe, since OptionValue's only exist in key-value pairs, 1472 // Holding this pointer is safe, since OptionValue's only exist in key-value pairs,
1476 // where the key has the string we point to. 1473 // where the key has the string we point to.
1477 std::shared_ptr<Value> m_value{}; 1474 std::shared_ptr<Value> m_value{};
1478 - size_t m_count = 0; 1475 + std::size_t m_count = 0;
1479 bool m_default = false; 1476 bool m_default = false;
1480 }; 1477 };
1481 1478
@@ -1516,8 +1513,8 @@ class KeyValue @@ -1516,8 +1513,8 @@ class KeyValue
1516 std::string m_value; 1513 std::string m_value;
1517 }; 1514 };
1518 1515
1519 -using ParsedHashMap = std::unordered_map<size_t, OptionValue>;  
1520 -using NameHashMap = std::unordered_map<std::string, size_t>; 1516 +using ParsedHashMap = std::unordered_map<std::size_t, OptionValue>;
  1517 +using NameHashMap = std::unordered_map<std::string, std::size_t>;
1521 1518
1522 class ParseResult 1519 class ParseResult
1523 { 1520 {
@@ -1611,7 +1608,7 @@ class ParseResult @@ -1611,7 +1608,7 @@ class ParseResult
1611 return Iterator(this, true); 1608 return Iterator(this, true);
1612 } 1609 }
1613 1610
1614 - size_t 1611 + std::size_t
1615 count(const std::string& o) const 1612 count(const std::string& o) const
1616 { 1613 {
1617 auto iter = m_keys.find(o); 1614 auto iter = m_keys.find(o);
@@ -1821,7 +1818,7 @@ class Options @@ -1821,7 +1818,7 @@ class Options
1821 } 1818 }
1822 1819
1823 Options& 1820 Options&
1824 - set_width(size_t width) 1821 + set_width(std::size_t width)
1825 { 1822 {
1826 m_width = width; 1823 m_width = width;
1827 return *this; 1824 return *this;
@@ -1939,7 +1936,7 @@ class Options @@ -1939,7 +1936,7 @@ class Options
1939 std::string m_positional_help{}; 1936 std::string m_positional_help{};
1940 bool m_show_positional; 1937 bool m_show_positional;
1941 bool m_allow_unrecognised; 1938 bool m_allow_unrecognised;
1942 - size_t m_width; 1939 + std::size_t m_width;
1943 bool m_tab_expansion; 1940 bool m_tab_expansion;
1944 1941
1945 std::shared_ptr<OptionMap> m_options; 1942 std::shared_ptr<OptionMap> m_options;
@@ -1975,8 +1972,8 @@ class OptionAdder @@ -1975,8 +1972,8 @@ class OptionAdder
1975 }; 1972 };
1976 1973
1977 namespace { 1974 namespace {
1978 -constexpr size_t OPTION_LONGEST = 30;  
1979 -constexpr size_t OPTION_DESC_GAP = 2; 1975 +constexpr std::size_t OPTION_LONGEST = 30;
  1976 +constexpr std::size_t OPTION_DESC_GAP = 2;
1980 1977
1981 String 1978 String
1982 format_option 1979 format_option
@@ -2028,8 +2025,8 @@ String @@ -2028,8 +2025,8 @@ String
2028 format_description 2025 format_description
2029 ( 2026 (
2030 const HelpOptionDetails& o, 2027 const HelpOptionDetails& o,
2031 - size_t start,  
2032 - size_t allowed, 2028 + std::size_t start,
  2029 + std::size_t allowed,
2033 bool tab_expansion 2030 bool tab_expansion
2034 ) 2031 )
2035 { 2032 {
@@ -2052,7 +2049,7 @@ format_description @@ -2052,7 +2049,7 @@ format_description
2052 if (tab_expansion) 2049 if (tab_expansion)
2053 { 2050 {
2054 String desc2; 2051 String desc2;
2055 - auto size = size_t{ 0 }; 2052 + auto size = std::size_t{ 0 };
2056 for (auto c = std::begin(desc); c != std::end(desc); ++c) 2053 for (auto c = std::begin(desc); c != std::end(desc); ++c)
2057 { 2054 {
2058 if (*c == '\n') 2055 if (*c == '\n')
@@ -2082,7 +2079,7 @@ format_description @@ -2082,7 +2079,7 @@ format_description
2082 auto startLine = current; 2079 auto startLine = current;
2083 auto lastSpace = current; 2080 auto lastSpace = current;
2084 2081
2085 - auto size = size_t{}; 2082 + auto size = std::size_t{};
2086 2083
2087 bool appendNewLine; 2084 bool appendNewLine;
2088 bool onlyWhiteSpace = true; 2085 bool onlyWhiteSpace = true;
@@ -2090,13 +2087,11 @@ format_description @@ -2090,13 +2087,11 @@ format_description
2090 while (current != std::end(desc)) 2087 while (current != std::end(desc))
2091 { 2088 {
2092 appendNewLine = false; 2089 appendNewLine = false;
2093 -  
2094 - if (std::isblank(*previous, std::locale::classic())) 2090 + if (*previous == ' ' || *previous == '\t')
2095 { 2091 {
2096 lastSpace = current; 2092 lastSpace = current;
2097 } 2093 }
2098 -  
2099 - if (!std::isblank(*current, std::locale::classic())) 2094 + if (*current != ' ' && *current != '\t')
2100 { 2095 {
2101 onlyWhiteSpace = false; 2096 onlyWhiteSpace = false;
2102 } 2097 }
@@ -2622,7 +2617,7 @@ Options::help_one_group(const std::string&amp; g) const @@ -2622,7 +2617,7 @@ Options::help_one_group(const std::string&amp; g) const
2622 2617
2623 OptionHelp format; 2618 OptionHelp format;
2624 2619
2625 - size_t longest = 0; 2620 + std::size_t longest = 0;
2626 2621
2627 String result; 2622 String result;
2628 2623
@@ -2647,7 +2642,7 @@ Options::help_one_group(const std::string&amp; g) const @@ -2647,7 +2642,7 @@ Options::help_one_group(const std::string&amp; g) const
2647 longest = (std::min)(longest, OPTION_LONGEST); 2642 longest = (std::min)(longest, OPTION_LONGEST);
2648 2643
2649 //widest allowed description -- min 10 chars for helptext/line 2644 //widest allowed description -- min 10 chars for helptext/line
2650 - size_t allowed = 10; 2645 + std::size_t allowed = 10;
2651 if (m_width > allowed + longest + OPTION_DESC_GAP) 2646 if (m_width > allowed + longest + OPTION_DESC_GAP)
2652 { 2647 {
2653 allowed = m_width - longest - OPTION_DESC_GAP; 2648 allowed = m_width - longest - OPTION_DESC_GAP;
@@ -2694,7 +2689,7 @@ Options::generate_group_help @@ -2694,7 +2689,7 @@ Options::generate_group_help
2694 const std::vector<std::string>& print_groups 2689 const std::vector<std::string>& print_groups
2695 ) const 2690 ) const
2696 { 2691 {
2697 - for (size_t i = 0; i != print_groups.size(); ++i) 2692 + for (std::size_t i = 0; i != print_groups.size(); ++i)
2698 { 2693 {
2699 const String& group_help_text = help_one_group(print_groups[i]); 2694 const String& group_help_text = help_one_group(print_groups[i]);
2700 if (empty(group_help_text)) 2695 if (empty(group_help_text))