diff --git a/common/Makefile.am b/common/Makefile.am index 834f5d49..fa158032 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -37,7 +37,7 @@ libsynaptic_a_SOURCES =\ rcacheactor.cc \ rcacheactor.h \ rpackagemanager.cc \ - rpackagemanager.h \ + rpackagemanager.h \ rpackagelistactor.cc \ rpackagelistactor.h \ rtagcollbuilder.cc \ @@ -51,4 +51,3 @@ libsynaptic_a_SOURCES =\ sections_trans.h \ sections_trans.cc - diff --git a/common/rsource_deb822.cc b/common/rsource_deb822.cc index 00dc524b..be904c65 100644 --- a/common/rsource_deb822.cc +++ b/common/rsource_deb822.cc @@ -14,91 +14,123 @@ #include "i18n.h" #include #include +#include + +namespace { +std::string Trimmed(std::string value) { + RDeb822Source::TrimWhitespace(value); + return value; +} + +std::string JoinComments(const std::vector& comments) { + std::stringstream commentStream; + for (size_t i = 0; i < comments.size(); ++i) { + if (i > 0) { + commentStream << std::endl; + } + commentStream << comments[i]; + } + return commentStream.str(); +} + +bool AddEntryFromFields(const std::map& fields, + const std::vector& comments, + std::vector& entries) { + if (fields.find("Types") == fields.end() || + fields.find("URIs") == fields.end() || + fields.find("Suites") == fields.end()) { + return false; + } + + RDeb822Source::Deb822Entry entry; + entry.Types = fields.at("Types"); + entry.URIs = fields.at("URIs"); + entry.Suites = fields.at("Suites"); + entry.Components = fields.count("Components") ? fields.at("Components") : ""; + entry.SignedBy = fields.count("Signed-By") ? fields.at("Signed-By") : ""; + entry.Architectures = fields.count("Architectures") ? fields.at("Architectures") : ""; + entry.Languages = fields.count("Languages") ? fields.at("Languages") : ""; + entry.Targets = fields.count("Targets") ? fields.at("Targets") : ""; + entry.Comment = JoinComments(comments); + + if (fields.count("Enabled")) { + std::string enabled_val = fields.at("Enabled"); + std::transform(enabled_val.begin(), enabled_val.end(), enabled_val.begin(), ::tolower); + entry.Enabled = (enabled_val == "yes" || enabled_val == "true" || enabled_val == "1"); + } else if (fields.count("Disabled")) { + std::string disabled_val = fields.at("Disabled"); + std::transform(disabled_val.begin(), disabled_val.end(), disabled_val.begin(), ::tolower); + entry.Enabled = !(disabled_val == "yes" || disabled_val == "true" || disabled_val == "1"); + } else { + entry.Enabled = true; + } + + entries.push_back(entry); + return true; +} +} bool RDeb822Source::ParseDeb822File(const std::string& path, std::vector& entries) { std::ifstream file(path); if (!file.is_open()) { return false; } + + entries.clear(); std::string line; std::map fields; - int stanza_count = 0; + std::vector comments; + std::string currentKey; + bool sawFields = false; + while (std::getline(file, line)) { - if (line.empty()) { + if (!line.empty() && line.back() == '\r') { + line.pop_back(); + } + std::string trimmedLine = Trimmed(line); + + if (trimmedLine.empty()) { if (!fields.empty()) { - Deb822Entry entry; - // Check required fields - if (fields.find("Types") == fields.end() || fields.find("URIs") == fields.end() || fields.find("Suites") == fields.end()) { - fields.clear(); - continue; - } - entry.Types = fields["Types"]; - entry.URIs = fields["URIs"]; - entry.Suites = fields["Suites"]; - entry.Components = fields.count("Components") ? fields["Components"] : ""; - entry.SignedBy = fields.count("Signed-By") ? fields["Signed-By"] : ""; - // Handle Enabled/Disabled fields - if (fields.count("Enabled")) { - std::string enabled_val = fields["Enabled"]; - std::transform(enabled_val.begin(), enabled_val.end(), enabled_val.begin(), ::tolower); - entry.Enabled = (enabled_val == "yes" || enabled_val == "true" || enabled_val == "1"); - } else if (fields.count("Disabled")) { - std::string disabled_val = fields["Disabled"]; - std::transform(disabled_val.begin(), disabled_val.end(), disabled_val.begin(), ::tolower); - entry.Enabled = !(disabled_val == "yes" || disabled_val == "true" || disabled_val == "1"); - } else { - entry.Enabled = true; // Default to enabled - } - entries.push_back(entry); - stanza_count++; + AddEntryFromFields(fields, comments, entries); fields.clear(); + comments.clear(); + currentKey.clear(); + } else { + comments.clear(); } continue; } + if (line[0] == '#') { + comments.push_back(line); continue; } + + if (std::isspace(static_cast(line[0])) && !currentKey.empty()) { + fields[currentKey] += "\n" + trimmedLine; + continue; + } + size_t colon = line.find(':'); if (colon == std::string::npos) { continue; } + std::string key = line.substr(0, colon); std::string value = line.substr(colon + 1); - // Trim whitespace - key.erase(0, key.find_first_not_of(" \t")); - key.erase(key.find_last_not_of(" \t") + 1); - value.erase(0, value.find_first_not_of(" \t")); - value.erase(value.find_last_not_of(" \t") + 1); + TrimWhitespace(key); + TrimWhitespace(value); fields[key] = value; + currentKey = key; + sawFields = true; } + // Handle last stanza if file does not end with blank line if (!fields.empty()) { - Deb822Entry entry; - if (fields.find("Types") == fields.end() || fields.find("URIs") == fields.end() || fields.find("Suites") == fields.end()) { - // No debug print, just skip - } else { - entry.Types = fields["Types"]; - entry.URIs = fields["URIs"]; - entry.Suites = fields["Suites"]; - entry.Components = fields.count("Components") ? fields["Components"] : ""; - entry.SignedBy = fields.count("Signed-By") ? fields["Signed-By"] : ""; - // Handle Enabled/Disabled fields - if (fields.count("Enabled")) { - std::string enabled_val = fields["Enabled"]; - std::transform(enabled_val.begin(), enabled_val.end(), enabled_val.begin(), ::tolower); - entry.Enabled = (enabled_val == "yes" || enabled_val == "true" || enabled_val == "1"); - } else if (fields.count("Disabled")) { - std::string disabled_val = fields["Disabled"]; - std::transform(disabled_val.begin(), disabled_val.end(), disabled_val.begin(), ::tolower); - entry.Enabled = !(disabled_val == "yes" || disabled_val == "true" || disabled_val == "1"); - } else { - entry.Enabled = true; // Default to enabled - } - entries.push_back(entry); - stanza_count++; - } + AddEntryFromFields(fields, comments, entries); } - return true; + + return !entries.empty() || !sawFields; } bool RDeb822Source::WriteDeb822File(const std::string& path, const std::vector& entries) { @@ -332,4 +364,4 @@ bool RDeb822Source::ParseStanza(std::ifstream& file, std::mapshowErrors(); return false; @@ -420,9 +417,6 @@ bool RGRepositoryEditor::Run() if ((*it)->Type & SourcesList::Comment) continue; - // Add debug print for each source being added to the display - g_print("DEBUG: Adding source to display - URI: %s, Type: %s\n", (*it)->URI.c_str(), (*it)->GetType().c_str()); - string Sections; for (unsigned int J = 0; J < (*it)->NumSections; J++) { Sections += (*it)->Sections[J]; @@ -444,9 +438,6 @@ bool RGRepositoryEditor::Run() } // --- END NEW --- - // Add another debug print before appending to the list store - g_print("DEBUG: Preparing to append to list store for URI: %s\n", (*it)->URI.c_str()); - gtk_list_store_append(_sourcesListStore, &iter); gtk_list_store_set(_sourcesListStore, &iter, STATUS_COLUMN, !((*it)->Type & @@ -461,8 +452,6 @@ bool RGRepositoryEditor::Run() (*it)->Type & SourcesList::Disabled ? &_gray : NULL, -1); - // Add debug print after setting data in the list store - g_print("DEBUG: Successfully set data for URI: %s\n", (*it)->URI.c_str()); } diff --git a/tests/Makefile.am b/tests/Makefile.am index 4888444f..ddc66352 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -3,6 +3,8 @@ AM_CPPFLAGS = -I${top_srcdir}/common -I${top_srcdir}/gtk \ @GTK_CFLAGS@ @VTE_CFLAGS@ @LP_CFLAGS@ $(LIBTAGCOLL_CFLAGS) $(LIBEPT_CFLAGS) -O0 -g3 noinst_PROGRAMS = test_rpackage test_rpackageview test_gtkpkglist test_rpackagefilter +check_PROGRAMS = test_deb822_integration +TESTS = $(check_PROGRAMS) LDADD = \ ${top_builddir}/common/libsynaptic.a\ @@ -22,5 +24,7 @@ test_gtkpkglist_SOURCES= test_gtkpkglist.cc \ ${top_srcdir}/gtk/rgpkgtreeview.cc\ ${top_srcdir}/gtk/gtkpkglist.cc -CLEANFILES= $(wildcard *_wrap.*) $(wildcard *~) +test_deb822_integration_SOURCES = test_deb822_integration.cc +test_deb822_integration_LDADD = $(LDADD) -lgtest +CLEANFILES= $(wildcard *_wrap.*) $(wildcard *~) diff --git a/tests/test_deb822_integration.cc b/tests/test_deb822_integration.cc index a689cd0e..566eaa31 100644 --- a/tests/test_deb822_integration.cc +++ b/tests/test_deb822_integration.cc @@ -5,6 +5,12 @@ #include #include #include +#include + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} class Deb822Test : public ::testing::Test { protected: @@ -209,7 +215,7 @@ TEST_F(Deb822Test, SourcesListIntegration) { // Clean up remove(newFile.c_str()); -} +} TEST_F(Deb822Test, ParseAdditionalFields) { std::ofstream ofs(testFile.c_str()); @@ -304,8 +310,7 @@ TEST_F(Deb822Test, WriteAndReadAdditionalFields) { // Read it back std::vector entries; - std::string error; - EXPECT_TRUE(RDeb822Source::ParseDeb822File(tempFile, entries, error)) << error; + EXPECT_TRUE(RDeb822Source::ParseDeb822File(tempFile, entries)); EXPECT_EQ(entries.size(), 1); // Verify fields @@ -321,4 +326,4 @@ TEST_F(Deb822Test, WriteAndReadAdditionalFields) { // Clean up std::remove(tempFile.c_str()); -} \ No newline at end of file +}