TEST(CLDataPostChannelBySTLqueueMaintainer, FunctionReturnRight) { CLLogger::WriteLogMsg("CLDataPostChannelBySTLqueueMaintainer Test", 0); CLSTLqueue *q = new CLSTLqueue(); CLDataPostChannelBySTLqueueMaintainer maintainer(q); CLInitialDataPostChannelNotifier *notifier = new CLInitialDataPostChannelNotifier(); EXPECT_TRUE(maintainer.Initialize(notifier, 0).IsSuccess()); CLDataPoster *poster = maintainer.GetDataPoster(); CLDataPosterBySTLqueue *pq = dynamic_cast<CLDataPosterBySTLqueue *>(poster); EXPECT_TRUE(pq != 0); delete poster; }
/** \brief Parse a line from a version entry. * * This function reads the header (one line), a list of logs, and then * the footer of a version entry. * * If a version exists, even if it is wrong, the function returns true. * The function returns false if the end of the file is reached. * * \param[in] s The state to read from. * * \return true if the end of the file was not yet reached when this * version was read in full. */ bool changelog_file::version::parse(state& s) { f_filename = s.get_filename(); f_line = s.get_line(); // the current line must be the header if(s.space_count() != 0) { wpkg_output::log("changelog:%1:%2: a changelog version entry must start with a valid header") .arg(f_filename) .arg(f_line) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .action("changelog"); return s.next_line(); } bool good_header(true); const std::string& header(s.last_line()); const char *h(header.c_str()); const char *start(h); // *** Package Name *** for(; !isspace(*h) && *h != '('; ++h) { if(*h == '\0') { wpkg_output::log("changelog:%1:%2: invalid header, expected the project name, version, distributions, and urgency information") .arg(f_filename) .arg(f_line) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .action("changelog"); good_header = false; break; } } if(good_header) { std::string package_name(start, h - start); if(!wpkg_util::is_package_name(package_name)) { wpkg_output::log("changelog:%1:%2: the package name %3 is not valid") .arg(f_filename) .arg(f_line) .quoted_arg(package_name) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .action("changelog"); } else { f_package = package_name; } if(!isspace(*h)) { // this is just a warning, but the user is expected to put a space // after the package name and before the version wpkg_output::log("changelog:%1:%2: the package name %3 is not followed by a space before the version information") .arg(f_filename) .arg(f_line) .quoted_arg(package_name) .level(wpkg_output::level_warning) .module(wpkg_output::module_build_package) .package(f_package) .action("changelog"); good_header = false; } } // *** Version *** if(good_header) { for(; isspace(*h); ++h); if(*h != '(') { wpkg_output::log("changelog:%1:%2: invalid header, expected the version between parenthesis after the package name") .arg(f_filename) .arg(f_line) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .package(f_package) .action("changelog"); good_header = false; } } if(good_header) { // read the version ++h; start = h; for(; !isspace(*h) && *h != ')' && *h != '\0'; ++h); std::string version_str(start, h - start); char err[256]; if(!validate_debian_version(version_str.c_str(), err, sizeof(err))) { wpkg_output::log("control:%1:%2: %3 is not a valid Debian version") .arg(f_filename) .arg(f_line) .quoted_arg(version_str) .level(wpkg_output::level_error) .module(wpkg_output::module_changelog) .package(f_package) .action("changelog"); good_header = false; } else { f_version = version_str; } } if(good_header) { if(isspace(*h)) { for(; isspace(*h); ++h); wpkg_output::log("control:%1:%2: version %3 is not immediately followed by a closing parenthesis") .arg(f_filename) .arg(f_line) .quoted_arg(f_version) .level(wpkg_output::level_warning) .module(wpkg_output::module_changelog) .package(f_package) .action("changelog"); } if(*h != ')') { wpkg_output::log("control:%1:%2: version %3 is not followed by a closing parenthesis: ')'") .arg(f_filename) .arg(f_line) .quoted_arg(f_version) .level(wpkg_output::level_error) .module(wpkg_output::module_changelog) .package(f_package) .action("changelog"); good_header = false; } } // *** Distributions *** if(good_header) { // the first ++h is to skip the ')' from the version for(++h; isspace(*h); ++h); do { start = h; for(; !isspace(*h) && *h != '\0' && *h != ';' && *h != ','; ++h); std::string d(start, h - start); wpkg_filename::uri_filename distribution(d); if(distribution.is_absolute()) { wpkg_output::log("control:%1:%2: a distribution must be a relative path, %3 is not acceptable") .arg(f_filename) .arg(f_line) .quoted_arg(distribution) .level(wpkg_output::level_error) .module(wpkg_output::module_changelog) .package(f_package) .action("changelog"); good_header = false; } else if(distribution.segment_size() < 1) { // This happens if no distribution is specified wpkg_output::log("control:%1:%2: a distribution cannot be the empty string") .arg(f_filename) .arg(f_line) .level(wpkg_output::level_error) .module(wpkg_output::module_changelog) .package(f_package) .action("changelog"); good_header = false; } else { f_distributions.push_back(distribution.original_filename()); } for(; isspace(*h); ++h); } while(*h != '\0' && *h != ';' && *h != ','); } // We want to support more than one in source packages, that way a package // can be part of stable and unstable (because we view our distributions // as separate entities rather than complements.) //if(good_header) //{ // if(f_distributions.size() > 1) // { // wpkg_output::log("control:%1:%2: although the syntax allows for more than one distribution, we do not support more than one at this time") // .arg(f_filename) // .arg(f_line) // .level(wpkg_output::level_error) // .module(wpkg_output::module_changelog) // .package(f_package) // .action("changelog"); // good_header = false; // } //} // *** Parameters *** if(good_header) { for(; isspace(*h); ++h); if(*h != ';') { wpkg_output::log("changelog:%1:%2: invalid header, expected the list of distributions to end with ';'") .arg(f_filename) .arg(f_line) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .package(f_package) .action("changelog"); good_header = false; } else { for(++h; isspace(*h); ++h); } } while(good_header && *h != '\0') { start = h; const char *e(h); const char *equal(NULL); for(; *h != ',' && *h != '\0'; ++h) { if(!isspace(*h)) { e = h + 1; } if(*h == '=') { equal = h; } } if(equal == NULL) { wpkg_output::log("changelog:%1:%2: invalid header, parameter %3 is expected to include an equal sign (=) after the parameter name") .arg(f_filename) .arg(f_line) .quoted_arg(std::string(start, h - start)) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .package(f_package) .action("changelog"); good_header = false; } else if(start == equal) { wpkg_output::log("changelog:%1:%2: invalid header, parameter %3 is missing a name before the equal character") .arg(f_filename) .arg(f_line) .quoted_arg(std::string(start, h - start)) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .package(f_package) .action("changelog"); good_header = false; } else { std::string name(start, equal - start); if(f_parameters.find(name) != f_parameters.end()) { wpkg_output::log("changelog:%1:%2: invalid header, parameter %3 is defined twice") .arg(f_filename) .arg(f_line) .quoted_arg(name) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .package(f_package) .action("changelog"); good_header = false; } else { ++equal; std::string value(equal, e - equal); f_parameters[name] = value; } } // skip commas and spaces and repeat for next parameter for(; *h == ',' || isspace(*h); ++h); } // We got the header, now we check for the list of logs // the log::parse() function is expected to return false // once we reach the end of that list, then we must find // a footer that starts with a space and two dashes if(!s.next_line()) { wpkg_output::log("changelog:%1:%2: every changelog version entry must have at least one log and end with a valid footer") .arg(f_filename) .arg(s.get_line()) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .package(f_package) .action("changelog"); return false; } bool group(true); for(;;) { log l; if(!l.parse(s, group)) { break; } f_logs.push_back(l); } // we are at the end of the log stream for this version entry, // there has to be a valid footer now bool good_footer(true); if(s.space_count() != 1) { wpkg_output::log("changelog:%1:%2: a changelog version entry must end with a valid footer, which must start with exactly one space") .arg(f_filename) .arg(s.get_line()) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .package(f_package) .action("changelog"); good_footer = false; } const std::string& footer(s.last_line()); const char *f(footer.c_str()); if(good_footer) { if(f[0] != '-' || f[1] != '-' || f[2] != ' ') { wpkg_output::log("changelog:%1:%2: a changelog version entry must end with a valid footer, which must start with two dashes") .arg(f_filename) .arg(s.get_line()) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .package(f_package) .action("changelog"); good_footer = false; } } if(good_footer) { // search for two spaces to break the maintainer name/email and date f += 3; start = f; for(; f[0] != '\0' && (f[0] != ' ' || f[1] != ' '); ++f); std::string maintainer(start, f - start); // TODO: use libtld to verify email f_maintainer = maintainer; std::string date(f + 2); struct tm time_info; if(strptime(date.c_str(), "%a, %d %b %Y %H:%M:%S %z", &time_info) == NULL) { wpkg_output::log("changelog:%1:%2: the footer in this changelog version entry has an invalid date: %3") .arg(f_filename) .arg(s.get_line()) .quoted_arg(date) .level(wpkg_output::level_error) .module(wpkg_output::module_build_package) .package(f_package) .action("changelog"); good_footer = false; } else { f_date = date; } } // do not read another line in case this one is the next header return true; }