diff --git a/src/env_universal_common.cpp b/src/env_universal_common.cpp index 30d57978a..c925e29d0 100644 --- a/src/env_universal_common.cpp +++ b/src/env_universal_common.cpp @@ -56,7 +56,6 @@ #include #endif // Haiku - /// Error message. #define PARSE_ERR L"Unable to parse universal variable message: '%ls'" @@ -166,20 +165,30 @@ static bool append_utf8(const wcstring &input, std::string *receiver, std::strin /// Creates a file entry like "SET fish_color_cwd:FF0". Appends the result to *result (as UTF8). /// Returns true on success. storage may be used for temporary storage, to avoid allocations. -static bool append_file_entry(uvar_message_type_t type, const wcstring &key_in, +static bool append_file_entry(env_var_t::env_var_flags_t flags, const wcstring &key_in, const wcstring &val_in, std::string *result, std::string *storage) { + namespace f3 = fish3_uvars; assert(storage != NULL); assert(result != NULL); - namespace f2x = fish2x_uvars; // Record the length on entry, in case we need to back up. bool success = true; const size_t result_length_on_entry = result->size(); - // Append header like "SET " - result->append(type == uvar_message_type_t::set ? f2x::SET : f2x::SET_EXPORT); + // Append SETVAR header. + result->append(f3::SETUVAR); result->push_back(' '); + // Append flags. + if (flags & env_var_t::flag_export) { + result->append(f3::EXPORT); + result->push_back(' '); + } + if (flags & env_var_t::flag_pathvar) { + result->append(f3::PATH); + result->push_back(' '); + } + // Append variable name like "fish_color_cwd". if (!valid_var_name(key_in)) { debug(0, L"Illegal variable name: '%ls'", key_in.c_str()); @@ -407,15 +416,16 @@ bool env_universal_t::load_from_path(const wcstring &path, callback_data_list_t /// Serialize the contents to a string. std::string env_universal_t::serialize_with_vars(const var_table_t &vars) { std::string storage; - std::string contents = SAVE_MSG; + std::string contents; + contents.append(SAVE_MSG); + contents.append("# VERSION: " UVARS_VERSION_3_0 "\n"); + for (const auto &kv : vars) { // Append the entry. Note that append_file_entry may fail, but that only affects one // variable; soldier on. const wcstring &key = kv.first; const env_var_t &var = kv.second; - append_file_entry( - var.exports() ? uvar_message_type_t::set_export : uvar_message_type_t::set, key, - encode_serialized(var.as_list()), &contents, &storage); + append_file_entry(var.get_flags(), key, encode_serialized(var.as_list()), &contents, &storage); } return contents; } diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index dfc9ede61..c591196db 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -2890,14 +2890,26 @@ static void test_universal() { static void test_universal_output() { say(L"Testing universal variable output"); + + const env_var_t::env_var_flags_t flag_export = env_var_t::flag_export; + const env_var_t::env_var_flags_t flag_pathvar = env_var_t::flag_pathvar; + var_table_t vars; vars[L"varA"] = env_var_t(wcstring_list_t{L"ValA1", L"ValA2"}, 0); - vars[L"varB"] = env_var_t(wcstring_list_t{L"ValB1"}, env_var_t::flag_export); + vars[L"varB"] = env_var_t(wcstring_list_t{L"ValB1"}, flag_export); + vars[L"varC"] = env_var_t(wcstring_list_t{L"ValC1"}, 0); + vars[L"varD"] = env_var_t(wcstring_list_t{L"ValD1"}, flag_export | flag_pathvar); + vars[L"varE"] = env_var_t(wcstring_list_t{L"ValE1", L"ValE2"}, flag_pathvar); + std::string text = env_universal_t::serialize_with_vars(vars); const char *expected = "# This file contains fish universal variable definitions.\n" - "SET varA:ValA1\\x1eValA2\n" - "SET_EXPORT varB:ValB1\n"; + "# VERSION: 3.0\n" + "SETUVAR varA:ValA1\\x1eValA2\n" + "SETUVAR --export varB:ValB1\n" + "SETUVAR varC:ValC1\n" + "SETUVAR --export --path varD:ValD1\n" + "SETUVAR --path varE:ValE1\\x1eValE2\n"; do_test(text == expected); }