facter 3.9.6.cfacter.20180612 → 3.11.0.cfacter.20180319
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/facter/facter/CMakeLists.txt +1 -1
- data/ext/facter/facter/acceptance/Gemfile +3 -4
- data/ext/facter/facter/acceptance/Rakefile +342 -2
- data/ext/facter/facter/acceptance/config/aio/options.rb +6 -0
- data/ext/facter/facter/acceptance/config/git/options.rb +5 -1
- data/ext/facter/facter/acceptance/setup/aio/pre-suite/010_Install.rb +22 -0
- data/ext/facter/facter/acceptance/setup/aio/pre-suite/021_InstallAristaModule.rb +12 -0
- data/ext/facter/facter/acceptance/setup/aio/pre-suite/022_Remove_LD_PRELOAD.rb +11 -0
- data/ext/facter/facter/acceptance/setup/common/00_EnvSetup.rb +64 -0
- data/ext/facter/facter/acceptance/setup/common/pre-suite/000-delete-puppet-when-none.rb +11 -0
- data/ext/facter/facter/acceptance/setup/git/pre-suite/01_TestSetup.rb +31 -0
- data/ext/facter/facter/acceptance/tests/ticket_1238_hostname_fqdn.rb +20 -0
- data/ext/facter/facter/lib/CMakeLists.txt +3 -2
- data/ext/facter/facter/lib/Doxyfile +1 -1
- data/ext/facter/facter/lib/inc/facter/facts/fact.hpp +5 -0
- data/ext/facter/facter/lib/inc/internal/facts/aix/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/freebsd/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/linux/fips_resolver.hpp +31 -0
- data/ext/facter/facter/lib/inc/internal/facts/linux/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/openbsd/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/osx/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/posix/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/inc/internal/facts/resolvers/fips_resolver.hpp +46 -0
- data/ext/facter/facter/lib/inc/internal/facts/resolvers/networking_resolver.hpp +2 -3
- data/ext/facter/facter/lib/inc/internal/facts/resolvers/ssh_resolver.hpp +6 -0
- data/ext/facter/facter/lib/inc/internal/facts/solaris/networking_resolver.hpp +0 -7
- data/ext/facter/facter/lib/schema/facter.yaml +38 -18
- data/ext/facter/facter/lib/src/cwrapper.cc +5 -0
- data/ext/facter/facter/lib/src/facts/aix/disk_resolver.cc +2 -11
- data/ext/facter/facter/lib/src/facts/aix/networking_resolver.cc +0 -5
- data/ext/facter/facter/lib/src/facts/freebsd/dmi_resolver.cc +5 -1
- data/ext/facter/facter/lib/src/facts/freebsd/networking_resolver.cc +1 -10
- data/ext/facter/facter/lib/src/facts/freebsd/virtualization_resolver.cc +1 -4
- data/ext/facter/facter/lib/src/facts/linux/collection.cc +2 -0
- data/ext/facter/facter/lib/src/facts/linux/fips_resolver.cc +31 -0
- data/ext/facter/facter/lib/src/facts/linux/networking_resolver.cc +1 -10
- data/ext/facter/facter/lib/src/facts/openbsd/networking_resolver.cc +1 -10
- data/ext/facter/facter/lib/src/facts/osx/networking_resolver.cc +1 -10
- data/ext/facter/facter/lib/src/facts/posix/networking_resolver.cc +2 -3
- data/ext/facter/facter/lib/src/facts/posix/ssh_resolver.cc +3 -2
- data/ext/facter/facter/lib/src/facts/resolvers/fips_resolver.cc +23 -0
- data/ext/facter/facter/lib/src/facts/resolvers/networking_resolver.cc +7 -23
- data/ext/facter/facter/lib/src/facts/resolvers/ssh_resolver.cc +1 -0
- data/ext/facter/facter/lib/src/facts/solaris/networking_resolver.cc +0 -5
- data/ext/facter/facter/lib/tests/facts/resolvers/ssh_resolver.cc +8 -1
- data/ext/facter/facter/lib/tests/facts/schema.cc +17 -0
- data/ext/facter/facter/locales/FACTER.pot +2 -23
- data/ext/facter/leatherman/CHANGELOG.md +16 -9
- data/ext/facter/leatherman/CMakeLists.txt +1 -2
- data/ext/facter/leatherman/appveyor.yml +26 -19
- data/ext/facter/leatherman/catch/CMakeLists.txt +1 -1
- data/ext/facter/leatherman/curl/tests/client_test.cc +396 -398
- data/ext/facter/leatherman/curl/tests/mock_curl.cc +2 -0
- data/ext/facter/leatherman/curl/tests/request_test.cc +66 -68
- data/ext/facter/leatherman/curl/tests/response_test.cc +50 -52
- data/ext/facter/leatherman/dynamic_library/tests/dynamic_library_tests.cc +71 -75
- data/ext/facter/leatherman/execution/src/execution.cc +3 -0
- data/ext/facter/leatherman/execution/src/posix/execution.cc +5 -6
- data/ext/facter/leatherman/execution/src/windows/execution.cc +2 -0
- data/ext/facter/leatherman/execution/tests/windows/execution.cc +4 -2
- data/ext/facter/leatherman/file_util/tests/directory_utils_test.cc +66 -68
- data/ext/facter/leatherman/file_util/tests/file_utils_test.cc +175 -177
- data/ext/facter/leatherman/json_container/inc/leatherman/json_container/json_container.hpp +7 -0
- data/ext/facter/leatherman/json_container/src/json_container.cc +10 -1
- data/ext/facter/leatherman/json_container/tests/json_container_test.cc +152 -8
- data/ext/facter/leatherman/locale/CMakeLists.txt +0 -7
- data/ext/facter/leatherman/locales/leatherman.pot +8 -13
- data/ext/facter/leatherman/logging/src/logging.cc +2 -0
- data/ext/facter/leatherman/util/tests/timer.cc +1 -3
- data/ext/facter/leatherman/vendor/Catch-1.10.0.zip +0 -0
- data/ext/facter/leatherman/vendor/nowide/doc/Doxyfile +4 -4
- data/ext/facter/leatherman/vendor/nowide/doc/LICENSE_1_0.txt +23 -0
- data/ext/facter/leatherman/vendor/nowide/doc/main.txt +62 -54
- data/ext/facter/leatherman/vendor/nowide/include/boost/nowide/convert.hpp +16 -16
- data/ext/facter/leatherman/vendor/nowide/include/boost/nowide/cstdio.hpp +4 -4
- data/ext/facter/leatherman/vendor/nowide/include/boost/nowide/utf8_codecvt.hpp +1 -1
- data/ext/facter/leatherman/vendor/nowide/src/iostream.cpp +32 -30
- data/ext/facter/leatherman/vendor/nowide/standalone/convert +6 -6
- data/ext/facter/leatherman/vendor/nowide/standalone/encoding_utf.hpp +1 -1
- data/ext/facter/leatherman/vendor/nowide/standalone/run_convert_and_build.sh +1 -3
- metadata +15 -6
- data/ext/facter/leatherman/cmake/FindICU.cmake +0 -690
- data/ext/facter/leatherman/scripts/travis_target.sh +0 -79
- data/ext/facter/leatherman/vendor/catch-1.4.0.zip +0 -0
@@ -20,6 +20,9 @@ namespace rapidjson {
|
|
20
20
|
} // namespace rapidjson
|
21
21
|
|
22
22
|
namespace leatherman { namespace json_container {
|
23
|
+
// Constants
|
24
|
+
constexpr size_t DEFAULT_LEFT_PADDING { 4 };
|
25
|
+
|
23
26
|
// Errors
|
24
27
|
|
25
28
|
/// Parent error class.
|
@@ -139,9 +142,13 @@ namespace leatherman { namespace json_container {
|
|
139
142
|
/// Throw a data_key_error in case the specified key is unknown.
|
140
143
|
std::string toString(const std::vector<JsonContainerKey>& keys) const;
|
141
144
|
|
145
|
+
// TODO: Refactor this to use a default parameter of DEFAULT_LEFT_PADDING
|
146
|
+
// for left_padding to remove the empty-argument variant.
|
142
147
|
std::string toPrettyString(size_t left_padding) const;
|
143
148
|
std::string toPrettyString() const;
|
144
149
|
|
150
|
+
std::string toPrettyJson(size_t left_padding = DEFAULT_LEFT_PADDING) const;
|
151
|
+
|
145
152
|
/// Return true if the root is an empty JSON array or an empty
|
146
153
|
/// JSON object, false otherwise.
|
147
154
|
bool empty() const;
|
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
#include <rapidjson/document.h>
|
5
5
|
#include <rapidjson/stringbuffer.h>
|
6
|
+
#include <rapidjson/prettywriter.h>
|
6
7
|
#include <rapidjson/writer.h>
|
7
8
|
#include <rapidjson/allocators.h>
|
8
9
|
#include <rapidjson/rapidjson.h>
|
@@ -12,7 +13,6 @@ using leatherman::locale::_;
|
|
12
13
|
|
13
14
|
namespace leatherman { namespace json_container {
|
14
15
|
|
15
|
-
const size_t DEFAULT_LEFT_PADDING { 4 };
|
16
16
|
const size_t LEFT_PADDING_INCREMENT { 2 };
|
17
17
|
|
18
18
|
//
|
@@ -146,6 +146,15 @@ namespace leatherman { namespace json_container {
|
|
146
146
|
return toPrettyString(DEFAULT_LEFT_PADDING);
|
147
147
|
}
|
148
148
|
|
149
|
+
std::string JsonContainer::toPrettyJson(size_t left_padding) const {
|
150
|
+
rapidjson::StringBuffer buffer;
|
151
|
+
rapidjson::PrettyWriter<rapidjson::StringBuffer> writer { buffer };
|
152
|
+
writer.SetIndent(' ', left_padding);
|
153
|
+
auto& jval = *getValueInJson();
|
154
|
+
jval.Accept(writer);
|
155
|
+
return buffer.GetString();
|
156
|
+
}
|
157
|
+
|
149
158
|
// capacity
|
150
159
|
|
151
160
|
bool JsonContainer::empty() const {
|
@@ -16,7 +16,7 @@ static const std::string JSON = "{\"foo\" : {\"bar\" : 2},"
|
|
16
16
|
" }"
|
17
17
|
"}";
|
18
18
|
|
19
|
-
namespace leatherman
|
19
|
+
using namespace leatherman::json_container;
|
20
20
|
|
21
21
|
TEST_CASE("JsonContainer::JsonContainer - passing JSON string", "[data]") {
|
22
22
|
std::string json_value {};
|
@@ -149,7 +149,7 @@ TEST_CASE("JsonContainer::get for object entries", "[data]") {
|
|
149
149
|
}
|
150
150
|
|
151
151
|
SECTION("it can get the root object") {
|
152
|
-
|
152
|
+
REQUIRE(data.get<JsonContainer>().get<int>("goo") == 1);
|
153
153
|
}
|
154
154
|
|
155
155
|
SECTION("it should behave correctly given a null value") {
|
@@ -355,7 +355,7 @@ TEST_CASE("JsonContainer::get for object entries", "[data]") {
|
|
355
355
|
|
356
356
|
SECTION("array with values of different types") {
|
357
357
|
JsonContainer a { "[ 1, \"foo\", true, [2.718, 3.14], 42, 42.0, "
|
358
|
-
|
358
|
+
"{\"spam\":\"eggs\"} ]" };
|
359
359
|
|
360
360
|
SECTION("boolean") {
|
361
361
|
REQUIRE(a.get<bool>(2));
|
@@ -511,6 +511,152 @@ TEST_CASE("JsonContainer::toPrettyString", "[data]") {
|
|
511
511
|
}
|
512
512
|
}
|
513
513
|
|
514
|
+
TEST_CASE("JsonContainer::toPrettyJson", "[data]") {
|
515
|
+
SECTION("it pretty prints valid json") {
|
516
|
+
SECTION("a null value") {
|
517
|
+
std::string EXPECTED_OUTPUT = "null";
|
518
|
+
|
519
|
+
JsonContainer data(EXPECTED_OUTPUT);
|
520
|
+
auto pretty_json = data.toPrettyJson();
|
521
|
+
REQUIRE(pretty_json == EXPECTED_OUTPUT);
|
522
|
+
}
|
523
|
+
|
524
|
+
SECTION("a double") {
|
525
|
+
std::string EXPECTED_OUTPUT = "42.5";
|
526
|
+
|
527
|
+
JsonContainer data(EXPECTED_OUTPUT);
|
528
|
+
auto pretty_json = data.toPrettyJson();
|
529
|
+
REQUIRE(pretty_json == EXPECTED_OUTPUT);
|
530
|
+
}
|
531
|
+
|
532
|
+
SECTION("a bool") {
|
533
|
+
std::string EXPECTED_OUTPUT = "true";
|
534
|
+
|
535
|
+
JsonContainer data(EXPECTED_OUTPUT);
|
536
|
+
auto pretty_json = data.toPrettyJson();
|
537
|
+
REQUIRE(pretty_json == EXPECTED_OUTPUT);
|
538
|
+
}
|
539
|
+
|
540
|
+
SECTION("an int") {
|
541
|
+
std::string EXPECTED_OUTPUT = "42";
|
542
|
+
|
543
|
+
JsonContainer data(EXPECTED_OUTPUT);
|
544
|
+
auto pretty_json = data.toPrettyJson();
|
545
|
+
REQUIRE(pretty_json == EXPECTED_OUTPUT);
|
546
|
+
}
|
547
|
+
|
548
|
+
SECTION("a string") {
|
549
|
+
std::string EXPECTED_OUTPUT = "\"string\"";
|
550
|
+
|
551
|
+
JsonContainer data(EXPECTED_OUTPUT);
|
552
|
+
auto pretty_json = data.toPrettyJson();
|
553
|
+
REQUIRE(pretty_json == EXPECTED_OUTPUT);
|
554
|
+
}
|
555
|
+
|
556
|
+
SECTION("a simple array") {
|
557
|
+
std::string EXPECTED_OUTPUT =
|
558
|
+
"[\n"
|
559
|
+
" null,\n"
|
560
|
+
" 42.5,\n"
|
561
|
+
" true,\n"
|
562
|
+
" 42,\n"
|
563
|
+
" \"string\"\n"
|
564
|
+
"]";
|
565
|
+
|
566
|
+
JsonContainer data(EXPECTED_OUTPUT);
|
567
|
+
auto pretty_json = data.toPrettyJson();
|
568
|
+
REQUIRE(pretty_json == EXPECTED_OUTPUT);
|
569
|
+
}
|
570
|
+
|
571
|
+
SECTION("a simple object") {
|
572
|
+
std::string EXPECTED_OUTPUT =
|
573
|
+
"{\n"
|
574
|
+
" \"null-key\": null,\n"
|
575
|
+
" \"double-key\": 42.5,\n"
|
576
|
+
" \"bool-key\": true,\n"
|
577
|
+
" \"int-key\": 42,\n"
|
578
|
+
" \"string-key\": \"string\"\n"
|
579
|
+
"}";
|
580
|
+
|
581
|
+
JsonContainer data(EXPECTED_OUTPUT);
|
582
|
+
auto pretty_json = data.toPrettyJson();
|
583
|
+
REQUIRE(pretty_json == EXPECTED_OUTPUT);
|
584
|
+
}
|
585
|
+
|
586
|
+
SECTION("a nested object") {
|
587
|
+
std::string EXPECTED_OUTPUT =
|
588
|
+
"{\n"
|
589
|
+
" \"object-key\": {\n"
|
590
|
+
" \"null-key\": null,\n"
|
591
|
+
" \"double-key\": 42.5,\n"
|
592
|
+
" \"bool-key\": true,\n"
|
593
|
+
" \"int-key\": 42,\n"
|
594
|
+
" \"string-key\": \"string\"\n"
|
595
|
+
" },\n"
|
596
|
+
" \"array-key\": [\n"
|
597
|
+
" null,\n"
|
598
|
+
" 42.5,\n"
|
599
|
+
" true,\n"
|
600
|
+
" 42,\n"
|
601
|
+
" \"string\"\n"
|
602
|
+
" ]\n"
|
603
|
+
"}";
|
604
|
+
|
605
|
+
JsonContainer data(EXPECTED_OUTPUT);
|
606
|
+
auto pretty_json = data.toPrettyJson();
|
607
|
+
REQUIRE(pretty_json == EXPECTED_OUTPUT);
|
608
|
+
}
|
609
|
+
|
610
|
+
SECTION("a nested array") {
|
611
|
+
std::string EXPECTED_OUTPUT =
|
612
|
+
"[\n"
|
613
|
+
" {\n"
|
614
|
+
" \"null-key\": null,\n"
|
615
|
+
" \"double-key\": 42.5,\n"
|
616
|
+
" \"bool-key\": true,\n"
|
617
|
+
" \"int-key\": 42,\n"
|
618
|
+
" \"string-key\": \"string\"\n"
|
619
|
+
" },\n"
|
620
|
+
" [\n"
|
621
|
+
" null,\n"
|
622
|
+
" 42.5,\n"
|
623
|
+
" true,\n"
|
624
|
+
" 42,\n"
|
625
|
+
" \"string\"\n"
|
626
|
+
" ]\n"
|
627
|
+
"]";
|
628
|
+
|
629
|
+
JsonContainer data(EXPECTED_OUTPUT);
|
630
|
+
auto pretty_json = data.toPrettyJson();
|
631
|
+
REQUIRE(pretty_json == EXPECTED_OUTPUT);
|
632
|
+
}
|
633
|
+
}
|
634
|
+
|
635
|
+
SECTION("handles variable padding") {
|
636
|
+
std::string EXPECTED_OUTPUT =
|
637
|
+
"{\n"
|
638
|
+
" \"object-key\": {\n"
|
639
|
+
" \"null-key\": null,\n"
|
640
|
+
" \"double-key\": 42.5,\n"
|
641
|
+
" \"bool-key\": true,\n"
|
642
|
+
" \"int-key\": 42,\n"
|
643
|
+
" \"string-key\": \"string\"\n"
|
644
|
+
" },\n"
|
645
|
+
" \"array-key\": [\n"
|
646
|
+
" null,\n"
|
647
|
+
" 42.5,\n"
|
648
|
+
" true,\n"
|
649
|
+
" 42,\n"
|
650
|
+
" \"string\"\n"
|
651
|
+
" ]\n"
|
652
|
+
"}";
|
653
|
+
|
654
|
+
JsonContainer data(EXPECTED_OUTPUT);
|
655
|
+
auto pretty_json = data.toPrettyJson(2);
|
656
|
+
REQUIRE(pretty_json == EXPECTED_OUTPUT);
|
657
|
+
}
|
658
|
+
}
|
659
|
+
|
514
660
|
TEST_CASE("JsonContainer::empty", "[data]") {
|
515
661
|
SECTION("works correctly for an empty JsonContainer instance") {
|
516
662
|
JsonContainer data {};
|
@@ -754,8 +900,8 @@ TEST_CASE("JsonContainer::set", "[data]") {
|
|
754
900
|
TEST_CASE("JsonContainer::keys", "[data]") {
|
755
901
|
SECTION("It returns a vector of keys") {
|
756
902
|
JsonContainer data { "{ \"a\" : 1, "
|
757
|
-
|
758
|
-
|
903
|
+
" \"b\" : 2, "
|
904
|
+
" \"c\\u0000null\" : 2}" };
|
759
905
|
std::vector<std::string> expected_keys { "a", "b", { "c\0null", 6 } };
|
760
906
|
|
761
907
|
REQUIRE(data.keys() == expected_keys);
|
@@ -907,7 +1053,7 @@ TEST_CASE("JsonContainer::type", "[data]") {
|
|
907
1053
|
|
908
1054
|
TEST_CASE("JsonContainer::type for arrays entries", "[data]") {
|
909
1055
|
JsonContainer data { "[false, -42, 3.14, \"spam\", {\"foo\" : [3, true]}, "
|
910
|
-
|
1056
|
+
"[1, 2, 3, 4] ]" };
|
911
1057
|
|
912
1058
|
SECTION("root entry") {
|
913
1059
|
SECTION("array") {
|
@@ -981,5 +1127,3 @@ TEST_CASE("JsonContainer::type for arrays entries", "[data]") {
|
|
981
1127
|
}
|
982
1128
|
}
|
983
1129
|
}
|
984
|
-
|
985
|
-
}} // namespace leatherman::json_container
|
@@ -1,8 +1,5 @@
|
|
1
1
|
if (LEATHERMAN_USE_LOCALES)
|
2
2
|
find_package(Boost 1.54 REQUIRED COMPONENTS locale system)
|
3
|
-
if (BOOST_STATIC AND LEATHERMAN_USE_ICU)
|
4
|
-
find_package(ICU COMPONENTS i18n uc)
|
5
|
-
endif()
|
6
3
|
else()
|
7
4
|
find_package(Boost 1.54 REQUIRED regex)
|
8
5
|
endif()
|
@@ -10,10 +7,6 @@ endif()
|
|
10
7
|
add_leatherman_includes(${Boost_INCLUDE_DIRS})
|
11
8
|
add_leatherman_deps(${Boost_LIBRARIES})
|
12
9
|
|
13
|
-
if (ICU_LIBRARIES)
|
14
|
-
add_leatherman_deps(${ICU_LIBRARIES})
|
15
|
-
endif()
|
16
|
-
|
17
10
|
if (LEATHERMAN_USE_LOCALES AND BOOST_STATIC AND APPLE)
|
18
11
|
# Boost.Locale relies on libiconv; if not using shared boost libraries
|
19
12
|
# we need to include the dependency ourselves. So far this is only a
|
@@ -6,7 +6,7 @@
|
|
6
6
|
#, fuzzy
|
7
7
|
msgid ""
|
8
8
|
msgstr ""
|
9
|
-
"Project-Id-Version: leatherman 1.
|
9
|
+
"Project-Id-Version: leatherman 1.4.0\n"
|
10
10
|
"Report-Msgid-Bugs-To: docs@puppet.com\n"
|
11
11
|
"POT-Creation-Date: \n"
|
12
12
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
@@ -203,12 +203,7 @@ msgid "{1}: {2} ({3})."
|
|
203
203
|
msgstr ""
|
204
204
|
|
205
205
|
#: execution/src/posix/execution.cc
|
206
|
-
msgid "select call failed"
|
207
|
-
msgstr ""
|
208
|
-
|
209
|
-
#: execution/src/posix/execution.cc
|
210
|
-
#: execution/src/windows/execution.cc
|
211
|
-
msgid "child i/o failed."
|
206
|
+
msgid "select call failed waiting for child i/o"
|
212
207
|
msgstr ""
|
213
208
|
|
214
209
|
#. debug
|
@@ -267,15 +262,11 @@ msgid "waitpid failed"
|
|
267
262
|
msgstr ""
|
268
263
|
|
269
264
|
#: execution/src/posix/execution.cc
|
270
|
-
msgid "sigaction failed"
|
271
|
-
msgstr ""
|
272
|
-
|
273
|
-
#: execution/src/posix/execution.cc
|
274
|
-
msgid "failed to setup timer"
|
265
|
+
msgid "sigaction failed while setting up timeout"
|
275
266
|
msgstr ""
|
276
267
|
|
277
268
|
#: execution/src/posix/execution.cc
|
278
|
-
msgid "setitimer failed"
|
269
|
+
msgid "setitimer failed while setting up timeout"
|
279
270
|
msgstr ""
|
280
271
|
|
281
272
|
#. debug
|
@@ -353,6 +344,10 @@ msgstr ""
|
|
353
344
|
msgid "{1} pipe i/o failed: {2}."
|
354
345
|
msgstr ""
|
355
346
|
|
347
|
+
#: execution/src/windows/execution.cc
|
348
|
+
msgid "child i/o failed."
|
349
|
+
msgstr ""
|
350
|
+
|
356
351
|
#. error
|
357
352
|
#: execution/src/windows/execution.cc
|
358
353
|
msgid "failed to wait for child process i/o: {1}."
|
@@ -75,6 +75,7 @@ namespace leatherman { namespace logging {
|
|
75
75
|
_dst << endl;
|
76
76
|
}
|
77
77
|
|
78
|
+
// cppcheck-suppress passedByValue
|
78
79
|
void setup_logging(ostream &dst, string locale, string domain, bool use_locale)
|
79
80
|
{
|
80
81
|
// Remove existing sinks before adding a new one
|
@@ -149,6 +150,7 @@ namespace leatherman { namespace logging {
|
|
149
150
|
g_error_logged = false;
|
150
151
|
}
|
151
152
|
|
153
|
+
// cppcheck-suppress passedByValue
|
152
154
|
void on_message(function<bool(log_level, string const&)> callback)
|
153
155
|
{
|
154
156
|
g_callback = callback;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#include <catch.hpp>
|
2
2
|
#include <leatherman/util/timer.hpp>
|
3
3
|
|
4
|
-
namespace leatherman
|
4
|
+
using namespace leatherman::util;
|
5
5
|
|
6
6
|
SCENARIO("Using Timer", "[util]") {
|
7
7
|
SECTION("can instantiate") {
|
@@ -37,5 +37,3 @@ SCENARIO("Using Timer", "[util]") {
|
|
37
37
|
REQUIRE_NOTHROW(t.elapsed_milliseconds());
|
38
38
|
}
|
39
39
|
}
|
40
|
-
|
41
|
-
}} // namespace leatherman::util
|
Binary file
|
@@ -114,7 +114,7 @@ FULL_PATH_NAMES = YES
|
|
114
114
|
# If left blank the directory from which doxygen is run is used as the
|
115
115
|
# path to strip.
|
116
116
|
|
117
|
-
STRIP_FROM_PATH =
|
117
|
+
STRIP_FROM_PATH = ../include
|
118
118
|
|
119
119
|
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
|
120
120
|
# the path mentioned in the documentation of a class, which tells
|
@@ -123,7 +123,7 @@ STRIP_FROM_PATH = ../../..
|
|
123
123
|
# definition is used. Otherwise one should specify the include paths that
|
124
124
|
# are normally passed to the compiler using the -I flag.
|
125
125
|
|
126
|
-
STRIP_FROM_INC_PATH =
|
126
|
+
STRIP_FROM_INC_PATH = ../include
|
127
127
|
|
128
128
|
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
|
129
129
|
# (but less readable) file names. This can be useful is your file systems
|
@@ -581,7 +581,7 @@ WARN_LOGFILE =
|
|
581
581
|
# directories like "/usr/src/myproject". Separate the files or directories
|
582
582
|
# with spaces.
|
583
583
|
|
584
|
-
INPUT =
|
584
|
+
INPUT = ../include/boost/nowide ../include/boost/nowide/integration \
|
585
585
|
.
|
586
586
|
|
587
587
|
# This tag can be used to specify the character encoding of the source files
|
@@ -1349,7 +1349,7 @@ SEARCH_INCLUDES = YES
|
|
1349
1349
|
# contain include files that are not input files but should be processed by
|
1350
1350
|
# the preprocessor.
|
1351
1351
|
|
1352
|
-
INCLUDE_PATH =
|
1352
|
+
INCLUDE_PATH = ../include
|
1353
1353
|
|
1354
1354
|
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
|
1355
1355
|
# patterns (like *.h and *.hpp) to filter out the header-files in the
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Boost Software License - Version 1.0 - August 17th, 2003
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person or organization
|
4
|
+
obtaining a copy of the software and accompanying documentation covered by
|
5
|
+
this license (the "Software") to use, reproduce, display, distribute,
|
6
|
+
execute, and transmit the Software, and to prepare derivative works of the
|
7
|
+
Software, and to permit third-parties to whom the Software is furnished to
|
8
|
+
do so, all subject to the following:
|
9
|
+
|
10
|
+
The copyright notices in the Software and this entire statement, including
|
11
|
+
the above license grant, this restriction and the following disclaimer,
|
12
|
+
must be included in all copies of the Software, in whole or in part, and
|
13
|
+
all derivative works of the Software, unless such copies or derivative
|
14
|
+
works are solely in the form of machine-executable object code generated by
|
15
|
+
a source language processor.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
20
|
+
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
21
|
+
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
22
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
23
|
+
DEALINGS IN THE SOFTWARE.
|
@@ -22,6 +22,7 @@ Table of Contents:
|
|
22
22
|
- \ref using
|
23
23
|
- \ref using_standard
|
24
24
|
- \ref using_custom
|
25
|
+
- \ref using_integration
|
25
26
|
- \ref technical
|
26
27
|
- \ref technical_imple
|
27
28
|
- \ref technical_cio
|
@@ -32,7 +33,7 @@ Table of Contents:
|
|
32
33
|
\section main What is Boost.Nowide
|
33
34
|
|
34
35
|
Boost.Nowide is a library implemented by Artyom Beilis
|
35
|
-
that
|
36
|
+
that makes cross platform Unicode aware programming
|
36
37
|
easier.
|
37
38
|
|
38
39
|
The library provides an implementation of standard C and C++ library
|
@@ -45,22 +46,22 @@ requiring to use Wide API.
|
|
45
46
|
\subsection main_the_problem The Problem
|
46
47
|
|
47
48
|
Consider a simple application that splits a big file into chunks, such that
|
48
|
-
they can be sent by e-mail. It requires doing few very simple
|
49
|
+
they can be sent by e-mail. It requires doing a few very simple tasks:
|
49
50
|
|
50
51
|
- Access command line arguments: <code>int main(int argc,char **argv)</code>
|
51
|
-
- Open
|
52
|
+
- Open an input file, open several output files: <code>std::fstream::open(char const *,std::ios::openmode m)</code>
|
52
53
|
- Remove the files in case of fault: <code>std::remove(char const *file)</code>
|
53
|
-
- Print a progress report
|
54
|
+
- Print a progress report onto the console: <code>std::cout << file_name </code>
|
54
55
|
|
55
|
-
Unfortunately it is impossible to implement this simple task in
|
56
|
-
if the file names contain non-ASCII characters
|
56
|
+
Unfortunately it is impossible to implement this simple task in plain C++
|
57
|
+
if the file names contain non-ASCII characters.
|
57
58
|
|
58
59
|
The simple program that uses the API would work on the systems that use UTF-8
|
59
60
|
internally -- the vast majority of Unix-Line operating systems: Linux, Mac OS X,
|
60
61
|
Solaris, BSD. But it would fail on files like <code>War and Peace - Война и мир - מלחמה ושלום.zip</code>
|
61
|
-
under Microsoft Windows because the native Windows Unicode aware API is Wide-API
|
62
|
+
under Microsoft Windows because the native Windows Unicode aware API is Wide-API -- UTF-16.
|
62
63
|
|
63
|
-
This
|
64
|
+
This incredibly trivial task is very hard to implement in a cross platform manner.
|
64
65
|
|
65
66
|
\subsection main_the_solution The Solution
|
66
67
|
|
@@ -70,14 +71,14 @@ makes Unicode aware programming easier.
|
|
70
71
|
The library provides:
|
71
72
|
|
72
73
|
- Easy to use functions for converting UTF-8 to/from UTF-16
|
73
|
-
- A class to
|
74
|
+
- A class to make the \c argc, \c argc and \c env parameters of \c main use UTF-8
|
74
75
|
- UTF-8 aware functions
|
75
76
|
- \c stdio.h functions:
|
76
77
|
- \c fopen
|
77
78
|
- \c freopen
|
78
79
|
- \c remove
|
79
80
|
- \c rename
|
80
|
-
- \c stdlib.h functions
|
81
|
+
- \c stdlib.h functions:
|
81
82
|
- \c system
|
82
83
|
- \c getenv
|
83
84
|
- \c setenv
|
@@ -95,13 +96,13 @@ The library provides:
|
|
95
96
|
|
96
97
|
\subsection main_wide Why Not Narrow and Wide?
|
97
98
|
|
98
|
-
Why not
|
99
|
-
developer can choose to use Wide characters on Unix-
|
99
|
+
Why not provide both Wide and Narrow implementations so the
|
100
|
+
developer can choose to use Wide characters on Unix-like platforms?
|
100
101
|
|
101
102
|
Several reasons:
|
102
103
|
|
103
104
|
- \c wchar_t is not really portable, it can be 2 bytes, 4 bytes or even 1 byte making Unicode aware programming harder
|
104
|
-
-
|
105
|
+
- The C and C++ standard libraries use narrow strings for OS interactions. This library follows the same general rule. There is
|
105
106
|
no such thing as <code>fopen(wchar_t const *,wchar_t const *)</code> in the standard library, so it is better
|
106
107
|
to stick to the standards rather than re-implement Wide API in "Microsoft Windows Style"
|
107
108
|
|
@@ -114,12 +115,12 @@ Several reasons:
|
|
114
115
|
\section using Using The Library
|
115
116
|
\subsection using_standard Standard Features
|
116
117
|
|
117
|
-
The library is mostly header only
|
118
|
+
The library is mostly header only, only console I/O requires separate compilation under Windows.
|
118
119
|
|
119
|
-
As a developer you are expected to
|
120
|
+
As a developer you are expected to use \c boost::nowide functions instead of the functions available in the
|
120
121
|
\c std namespace.
|
121
122
|
|
122
|
-
For example, Unicode unaware implementation of line counter:
|
123
|
+
For example, here is a Unicode unaware implementation of a line counter:
|
123
124
|
\code
|
124
125
|
#include <fstream>
|
125
126
|
#include <iostream>
|
@@ -133,7 +134,7 @@ int main(int argc,char **argv)
|
|
133
134
|
|
134
135
|
std::ifstream f(argv[1]);
|
135
136
|
if(!f) {
|
136
|
-
std::cerr << "Can't open
|
137
|
+
std::cerr << "Can't open " << argv[1] << std::endl;
|
137
138
|
return 1;
|
138
139
|
}
|
139
140
|
int total_lines = 0;
|
@@ -147,7 +148,7 @@ int main(int argc,char **argv)
|
|
147
148
|
}
|
148
149
|
\endcode
|
149
150
|
|
150
|
-
To make this program handle Unicode properly we do the following changes:
|
151
|
+
To make this program handle Unicode properly, we do the following changes:
|
151
152
|
|
152
153
|
|
153
154
|
\code
|
@@ -166,7 +167,7 @@ int main(int argc,char **argv)
|
|
166
167
|
boost::nowide::ifstream f(argv[1]); // argv[1] - is UTF-8
|
167
168
|
if(!f) {
|
168
169
|
// the console can display UTF-8
|
169
|
-
boost::nowide::cerr << "Can't open
|
170
|
+
boost::nowide::cerr << "Can't open " << argv[1] << std::endl;
|
170
171
|
return 1;
|
171
172
|
}
|
172
173
|
int total_lines = 0;
|
@@ -181,30 +182,30 @@ int main(int argc,char **argv)
|
|
181
182
|
}
|
182
183
|
\endcode
|
183
184
|
|
184
|
-
This
|
185
|
+
This very simple and straightforward approach helps writing Unicode aware programs.
|
185
186
|
|
186
187
|
\subsection using_custom Custom API
|
187
188
|
|
188
|
-
Of course this simple set of functions does not cover all needs.
|
189
|
-
to access Wide API from Windows application
|
189
|
+
Of course, this simple set of functions does not cover all needs. If you need
|
190
|
+
to access Wide API from a Windows application that uses UTF-8 internally you can use
|
190
191
|
functions like \c boost::nowide::widen and \c boost::nowide::narrow.
|
191
192
|
|
192
|
-
For example
|
193
|
+
For example:
|
193
194
|
\code
|
194
195
|
CopyFileW( boost::nowide::widen(existing_file).c_str(),
|
195
196
|
boost::nowide::widen(new_file).c_str(),
|
196
197
|
TRUE);
|
197
198
|
\endcode
|
198
199
|
|
199
|
-
|
200
|
-
|
201
|
-
Wide API.
|
200
|
+
The conversion is done at the last stage, and you continue using UTF-8
|
201
|
+
strings everywhere else. You only switch to the Wide API at glue points.
|
202
202
|
|
203
203
|
\c boost::nowide::widen returns \c std::string. Sometimes
|
204
|
-
it is
|
205
|
-
|
204
|
+
it is useful to prevent allocation and use on-stack buffers
|
205
|
+
instead. Boost.Nowide provides the \c boost::nowide::basic_stackstring
|
206
|
+
class for this purpose.
|
206
207
|
|
207
|
-
|
208
|
+
The example above could be rewritten as:
|
208
209
|
|
209
210
|
\code
|
210
211
|
boost::nowide::basic_stackstring<wchar_t,char,64> wexisting_file,wnew_file;
|
@@ -216,25 +217,31 @@ if(!wexisting_file.convert(existing_file) || !wnew_file.convert(new_file)) {
|
|
216
217
|
CopyFileW(wexisting_file.c_str(),wnew_file.c_str(),TRUE);
|
217
218
|
\endcode
|
218
219
|
|
219
|
-
\note There are convenience typedefs \c stackstring
|
220
|
-
|
221
|
-
allocation
|
220
|
+
\note There are a few convenience typedefs: \c stackstring and \c wstackstring using
|
221
|
+
256-character buffers, and \c short_stackstring and \c wshort_stackstring using 16-character
|
222
|
+
buffers. If the string is longer, they fall back to memory allocation.
|
222
223
|
|
223
|
-
\subsection using_windows_h windows.h header
|
224
|
+
\subsection using_windows_h The windows.h header
|
224
225
|
|
225
226
|
The library does not include the \c windows.h in order to prevent namespace pollution with numerous
|
226
|
-
defines and types.
|
227
|
+
defines and types. Instead, the library defines the prototypes of the Win32 API functions.
|
228
|
+
|
229
|
+
However, you may request to use the \c windows.h header by defining \c BOOST_NOWIDE_USE_WINDOWS_H
|
230
|
+
before including any of the Boost.Nowide headers
|
231
|
+
|
232
|
+
\subsection using_integration Integration with Boost.Filesystem
|
233
|
+
|
234
|
+
Boost.Filesystem supports selection of narrow encoding. Unfortunatelly the default narrow encoding on Windows isn't UTF-8, you can enable UTF-8 as default encoding on Boost.Filesystem
|
235
|
+
by calling `boost::nowide::nowide_filesystem()` in the beginning of your program
|
227
236
|
|
228
|
-
However if you may request to use original \c windows.h header by setting \c BOOST_NOWIDE_USE_WINDOWS_H
|
229
|
-
define before including any of the Boost.Nowide headers
|
230
237
|
|
231
238
|
\section technical Technical Details
|
232
239
|
\subsection technical_imple Windows vs POSIX
|
233
240
|
|
234
|
-
|
235
|
-
|
241
|
+
For Microsoft Windows, the library provides UTF-8 aware variants of some \c std:: functions in the \c boost::nowide namespace.
|
242
|
+
For example, \c std::fopen becomes \c boost::nowide::fopen.
|
236
243
|
|
237
|
-
Under POSIX platforms the boost::nowide
|
244
|
+
Under POSIX platforms, the functions in boost::nowide are aliases of their standard library counterparts:
|
238
245
|
|
239
246
|
\code
|
240
247
|
namespace boost {
|
@@ -253,25 +260,26 @@ using std::fopen
|
|
253
260
|
|
254
261
|
\subsection technical_cio Console I/O
|
255
262
|
|
256
|
-
Console I/O implemented as wrapper
|
257
|
-
the stream
|
263
|
+
Console I/O is implemented as a wrapper around ReadConsoleW/WriteConsoleW
|
264
|
+
(used when the stream goes to the "real" console) and ReadFile/WriteFile
|
265
|
+
(used when the stream was piped/redirected).
|
258
266
|
|
259
267
|
This approach eliminates a need of manual code page handling. If TrueType
|
260
|
-
fonts are used the Unicode aware input and output
|
268
|
+
fonts are used the Unicode aware input and output works as intended.
|
261
269
|
|
262
270
|
\section qna Q & A
|
263
271
|
|
264
|
-
<b>Q: Why the library
|
272
|
+
<b>Q: Why doesn't the library convert the string to/from the locale's encoding (instead of UTF-8) on POSIX systems?</b>
|
265
273
|
|
266
274
|
A: It is inherently incorrect
|
267
275
|
to convert strings to/from locale encodings on POSIX platforms.
|
268
276
|
|
269
|
-
You can create a file named "\xFF\xFF.txt" (invalid UTF-8), remove it, pass its name as a parameter to program
|
270
|
-
and it would work whether the current locale is UTF-8
|
271
|
-
Also changing the locale from let's say \c en_US.UTF-8 to \c en_US.ISO-8859-1 would not magically change all
|
272
|
-
files in OS or the strings a user may pass to the program (which is different on Windows)
|
277
|
+
You can create a file named "\xFF\xFF.txt" (invalid UTF-8), remove it, pass its name as a parameter to a program
|
278
|
+
and it would work whether the current locale is UTF-8 or not.
|
279
|
+
Also, changing the locale from let's say \c en_US.UTF-8 to \c en_US.ISO-8859-1 would not magically change all
|
280
|
+
files in the OS or the strings a user may pass to the program (which is different on Windows)
|
273
281
|
|
274
|
-
POSIX OSs treat strings as \c
|
282
|
+
POSIX OSs treat strings as \c NULL terminated cookies.
|
275
283
|
|
276
284
|
So altering their content according to the locale would
|
277
285
|
actually lead to incorrect behavior.
|
@@ -283,21 +291,21 @@ For example, this is a naive implementation of a standard program "rm"
|
|
283
291
|
|
284
292
|
int main(int argc,char **argv)
|
285
293
|
{
|
286
|
-
|
287
|
-
|
288
|
-
|
294
|
+
for(int i=1;i<argc;i++)
|
295
|
+
std::remove(argv[i]);
|
296
|
+
return 0;
|
289
297
|
}
|
290
298
|
\endcode
|
291
299
|
|
292
300
|
It would work with ANY locale and changing the strings would
|
293
301
|
lead to incorrect behavior.
|
294
302
|
|
295
|
-
The meaning of a locale under POSIX and Windows
|
303
|
+
The meaning of a locale under POSIX and Windows platforms
|
296
304
|
is different and has very different effects.
|
297
305
|
|
298
306
|
\subsection standalone_version Standalone Version
|
299
307
|
|
300
|
-
It is possible to use Nowide library without
|
308
|
+
It is possible to use Nowide library without having the huge Boost project as a dependency. There is a standalone version that has all the functionality in the \c nowide namespace instead of \c boost::nowide. The example above would look like
|
301
309
|
|
302
310
|
\code
|
303
311
|
#include <nowide/args.hpp>
|
@@ -337,7 +345,7 @@ The upstream sources can be found at GitHub: <a href="https://github.com/artyom-
|
|
337
345
|
|
338
346
|
You can download the latest sources there:
|
339
347
|
|
340
|
-
- Standard Version: <a href="
|
348
|
+
- Standard Version: <a href="https://github.com/artyom-beilis/nowide/archive/master.zip">nowide-master.zip</a>
|
341
349
|
- Standalone Boost independent version <a href="../nowide_standalone.zip">nowide_standalone.zip</a>
|
342
350
|
|
343
351
|
*/
|