66
66
#include < codecvt>
67
67
68
68
#include < io.h> /* for _commit */
69
+ #include < shellapi.h>
69
70
#include < shlobj.h>
70
71
#endif
71
72
@@ -399,15 +400,17 @@ ArgsManager::ArgsManager() :
399
400
// nothing to do
400
401
}
401
402
402
- void ArgsManager::WarnForSectionOnlyArgs ()
403
+ const std::set<std::string> ArgsManager::GetUnsuitableSectionOnlyArgs () const
403
404
{
405
+ std::set<std::string> unsuitables;
406
+
404
407
LOCK (cs_args);
405
408
406
409
// if there's no section selected, don't worry
407
- if (m_network.empty ()) return ;
410
+ if (m_network.empty ()) return std::set<std::string> {} ;
408
411
409
412
// if it's okay to use the default section for this network, don't worry
410
- if (m_network == CBaseChainParams::MAIN) return ;
413
+ if (m_network == CBaseChainParams::MAIN) return std::set<std::string> {} ;
411
414
412
415
for (const auto & arg : m_network_only_args) {
413
416
std::pair<bool , std::string> found_result;
@@ -425,8 +428,29 @@ void ArgsManager::WarnForSectionOnlyArgs()
425
428
if (!found_result.first ) continue ;
426
429
427
430
// otherwise, issue a warning
428
- LogPrintf ( " Warning: Config setting for %s only applied on %s network when in [%s] section. \n " , arg, m_network, m_network );
431
+ unsuitables. insert ( arg);
429
432
}
433
+ return unsuitables;
434
+ }
435
+
436
+
437
+ const std::set<std::string> ArgsManager::GetUnrecognizedSections () const
438
+ {
439
+ // Section names to be recognized in the config file.
440
+ static const std::set<std::string> available_sections{
441
+ CBaseChainParams::REGTEST,
442
+ CBaseChainParams::TESTNET,
443
+ CBaseChainParams::MAIN,
444
+ CBaseChainParams::DEVNET
445
+ };
446
+ std::set<std::string> diff;
447
+
448
+ LOCK (cs_args);
449
+ std::set_difference (
450
+ m_config_sections.begin (), m_config_sections.end (),
451
+ available_sections.begin (), available_sections.end (),
452
+ std::inserter (diff, diff.end ()));
453
+ return diff;
430
454
}
431
455
432
456
void ArgsManager::SelectConfigNetwork (const std::string& network)
@@ -887,7 +911,7 @@ static std::string TrimString(const std::string& str, const std::string& pattern
887
911
return str.substr (front, end - front + 1 );
888
912
}
889
913
890
- static bool GetConfigOptions (std::istream& stream, std::string& error, std::vector<std::pair<std::string, std::string>> & options)
914
+ static bool GetConfigOptions (std::istream& stream, std::string& error, std::vector<std::pair<std::string, std::string>>& options, std::set<std::string>& sections )
891
915
{
892
916
std::string str, prefix;
893
917
std::string::size_type pos;
@@ -902,7 +926,9 @@ static bool GetConfigOptions(std::istream& stream, std::string& error, std::vect
902
926
str = TrimString (str, pattern);
903
927
if (!str.empty ()) {
904
928
if (*str.begin () == ' [' && *str.rbegin () == ' ]' ) {
905
- prefix = str.substr (1 , str.size () - 2 ) + ' .' ;
929
+ const std::string section = str.substr (1 , str.size () - 2 );
930
+ sections.insert (section);
931
+ prefix = section + ' .' ;
906
932
} else if (*str.begin () == ' -' ) {
907
933
error = strprintf (" parse error on line %i: %s, options in configuration file must be specified without leading -" , linenr, str);
908
934
return false ;
@@ -914,6 +940,9 @@ static bool GetConfigOptions(std::istream& stream, std::string& error, std::vect
914
940
return false ;
915
941
}
916
942
options.emplace_back (name, value);
943
+ if ((pos = name.rfind (' .' )) != std::string::npos) {
944
+ sections.insert (name.substr (0 , pos));
945
+ }
917
946
} else {
918
947
error = strprintf (" parse error on line %i: %s" , linenr, str);
919
948
if (str.size () >= 2 && str.substr (0 , 2 ) == " no" ) {
@@ -931,7 +960,8 @@ bool ArgsManager::ReadConfigStream(std::istream& stream, std::string& error, boo
931
960
{
932
961
LOCK (cs_args);
933
962
std::vector<std::pair<std::string, std::string>> options;
934
- if (!GetConfigOptions (stream, error, options)) {
963
+ m_config_sections.clear ();
964
+ if (!GetConfigOptions (stream, error, options, m_config_sections)) {
935
965
return false ;
936
966
}
937
967
for (const std::pair<std::string, std::string>& option : options) {
@@ -1298,6 +1328,10 @@ void SetupEnvironment()
1298
1328
} catch (const std::runtime_error&) {
1299
1329
setenv (" LC_ALL" , " C.UTF-8" , 1 );
1300
1330
}
1331
+ #elif defined(WIN32)
1332
+ // Set the default input/output charset is utf-8
1333
+ SetConsoleCP (CP_UTF8);
1334
+ SetConsoleOutputCP (CP_UTF8);
1301
1335
#endif
1302
1336
// The path locale is lazy initialized and to avoid deinitialization errors
1303
1337
// in multithreading environments, it is set explicitly by the main thread.
@@ -1367,3 +1401,30 @@ int ScheduleBatchPriority()
1367
1401
return 1 ;
1368
1402
#endif
1369
1403
}
1404
+
1405
+ namespace util {
1406
+ #ifdef WIN32
1407
+ WinCmdLineArgs::WinCmdLineArgs ()
1408
+ {
1409
+ wchar_t ** wargv = CommandLineToArgvW (GetCommandLineW (), &argc);
1410
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t >, wchar_t > utf8_cvt;
1411
+ argv = new char *[argc];
1412
+ args.resize (argc);
1413
+ for (int i = 0 ; i < argc; i++) {
1414
+ args[i] = utf8_cvt.to_bytes (wargv[i]);
1415
+ argv[i] = &*args[i].begin ();
1416
+ }
1417
+ LocalFree (wargv);
1418
+ }
1419
+
1420
+ WinCmdLineArgs::~WinCmdLineArgs ()
1421
+ {
1422
+ delete[] argv;
1423
+ }
1424
+
1425
+ std::pair<int , char **> WinCmdLineArgs::get ()
1426
+ {
1427
+ return std::make_pair (argc, argv);
1428
+ }
1429
+ #endif
1430
+ } // namespace util
0 commit comments