diff --git a/src/yycc/env.cpp b/src/yycc/env.cpp index d48999b..833e3a1 100644 --- a/src/yycc/env.cpp +++ b/src/yycc/env.cpp @@ -187,13 +187,19 @@ namespace yycc::env { while (*current != L'\0') { // Fetch current wide string std::wstring_view entry(current); + // Increase the pointer first, + // because in later steps we may enter next loop before reaching the end of this loop syntax. + current += entry.length() + 1; // Parse "KEY=VALUE" size_t pos = entry.find(L'='); if (pos != std::string::npos) { auto key = entry.substr(0, pos); auto value = entry.substr(pos + 1); - if (key.empty()) return std::unexpected(VarError::NullPointer); + // However, Idk why there are some shit words like "=::=::" are in this string list. + // This should be excluded and can not be seen as error. + // So we simply skip them and do not report error. + if (key.empty()) continue; auto u8key = ENC::to_utf8(key); auto u8value = ENC::to_utf8(value); @@ -205,9 +211,6 @@ namespace yycc::env { } else { return std::unexpected(VarError::Others); } - - // Increase the pointer - current += entry.length() + 1; } env_block.reset(); @@ -408,7 +411,7 @@ namespace yycc::env { if (argv == nullptr) return std::unexpected(ArgError::NullPointer); // Analyse it - for (int i = 1; i < argc; ++i) { // starts with 1 to remove first part (executable self) + for (int i = 0; i < argc; ++i) { // starts with 1 to remove first part (executable self) auto arg = argv.get()[i]; if (arg == nullptr) return std::unexpected(ArgError::NullPointer); diff --git a/src/yycc/env.hpp b/src/yycc/env.hpp index 2716be5..37aa45a 100644 --- a/src/yycc/env.hpp +++ b/src/yycc/env.hpp @@ -77,6 +77,9 @@ namespace yycc::env { */ VarResult> get_vars(); + // TODO: Add join_paths() and split_paths() for variable + // especially for PATH-like variable. + #pragma endregion #pragma region Environment Path diff --git a/test/yycc/env.cpp b/test/yycc/env.cpp index b9c84aa..6cc32b7 100644 --- a/test/yycc/env.cpp +++ b/test/yycc/env.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #define ENV ::yycc::env @@ -44,18 +43,40 @@ namespace yycctest::env { } } + TEST(Env, EnvVars) { + auto rv = ENV::get_vars(); + ASSERT_TRUE(rv.has_value()); + EXPECT_FALSE(rv.value().empty()); + } + + TEST(Env, CurrentDir) { + auto rv = ENV::current_dir(); + ASSERT_TRUE(rv.has_value()); + EXPECT_TRUE(std::filesystem::is_directory(rv.value())); + } + TEST(Env, CurrentExe) { auto rv = ENV::current_exe(); ASSERT_TRUE(rv.has_value()); + EXPECT_TRUE(std::filesystem::is_regular_file(rv.value())); + } - auto filename = rv.value().filename().u8string(); -#if defined(YYCC_OS_WINDOWS) - // Only Windows has special ext. - EXPECT_EQ(filename, u8"YYCCTest.exe"); -#else - // Executable in other system are all in plain name. - EXPECT_EQ(filename, u8"YYCCTest"); -#endif + TEST(Env, HomeDir) { + auto rv = ENV::home_dir(); + ASSERT_TRUE(rv.has_value()); + EXPECT_TRUE(std::filesystem::is_directory(rv.value())); + } + + TEST(Env, TempDir) { + auto rv = ENV::temp_dir(); + ASSERT_TRUE(rv.has_value()); + EXPECT_TRUE(std::filesystem::is_directory(rv.value())); + } + + TEST(Env, EnvArgs) { + auto rv = ENV::get_args(); + ASSERT_TRUE(rv.has_value()); + EXPECT_FALSE(rv.value().empty()); } } // namespace yycctest::env