00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <config.h>
00020
00021 #include "csbuild-debian-changes.h"
00022
00023 #include <fstream>
00024
00025 #include <boost/format.hpp>
00026
00027 using sbuild::_;
00028 using sbuild::N_;
00029 using boost::format;
00030 using namespace csbuild;
00031
00032 namespace
00033 {
00034
00035 typedef std::pair<debian_changes::error_code,const char *> emap;
00036
00041 emap init_errors[] =
00042 {
00043
00044 emap(debian_changes::BAD_FILE, N_("Can't open file '%1%'")),
00045
00046
00047 emap(debian_changes::DEPRECATED_KEY, N_("line %1%: Deprecated key '%4%' used")),
00048
00049 emap(debian_changes::DEPRECATED_KEY_NL, N_("Deprecated key '%4%' used")),
00050
00051
00052 emap(debian_changes::DISALLOWED_KEY, N_("line %1%: Disallowed key '%4%' used")),
00053
00054 emap(debian_changes::DISALLOWED_KEY_NL, N_("Disallowed key '%4%' used")),
00055
00056
00057 emap(debian_changes::DUPLICATE_KEY, N_("line %1%: Duplicate key '%4%'")),
00058
00059
00060 emap(debian_changes::INVALID_LINE, N_("line %1%: Invalid line: \"%4%\"")),
00061
00062
00063 emap(debian_changes::MISSING_KEY, N_("line %1%: Required key '%4%' is missing")),
00064
00065 emap(debian_changes::MISSING_KEY_NL, N_("Required key '%4%' is missing")),
00066
00067
00068 emap(debian_changes::NO_KEY, N_("line %1%: No key specified: \"%4%\"")),
00069
00070
00071 emap(debian_changes::OBSOLETE_KEY, N_("line %1%: Obsolete key '%4%' used")),
00072
00073 emap(debian_changes::OBSOLETE_KEY_NL, N_("Obsolete key '%4%' used")),
00074
00075
00076 emap(debian_changes::PASSTHROUGH_K, N_("%2%: %4%")),
00077
00078
00079
00080 emap(debian_changes::PASSTHROUGH_LK, N_("line %1%: %3%: %4%"))
00081 };
00082
00083 }
00084
00085 template<>
00086 sbuild::error<debian_changes::error_code>::map_type
00087 sbuild::error<debian_changes::error_code>::error_strings
00088 (init_errors,
00089 init_errors + (sizeof(init_errors) / sizeof(init_errors[0])));
00090
00091 debian_changes::debian_changes ():
00092 items()
00093 {
00094 }
00095
00096 debian_changes::debian_changes (std::string const& file):
00097 items()
00098 {
00099 std::ifstream fs(file.c_str());
00100 if (fs)
00101 {
00102 fs.imbue(std::locale::classic());
00103 fs >> *this;
00104 }
00105 else
00106 {
00107 throw error(file, BAD_FILE);
00108 }
00109 }
00110
00111 debian_changes::debian_changes (std::istream& stream):
00112 items()
00113 {
00114 stream >> *this;
00115 }
00116
00117 debian_changes::~debian_changes()
00118 {
00119 }
00120
00121 sbuild::string_list
00122 debian_changes::get_keys () const
00123 {
00124 sbuild::string_list ret;
00125
00126 for (item_map_type::const_iterator pos = items.begin();
00127 pos != items.end();
00128 ++pos)
00129 ret.push_back(pos->first);
00130
00131 return ret;
00132 }
00133
00134 bool
00135 debian_changes::has_key (key_type const& key) const
00136 {
00137 return (find_item(key) != 0);
00138 }
00139
00140 debian_changes::size_type
00141 debian_changes::get_line (key_type const& key) const
00142 {
00143 const item_type *found_item = find_item(key);
00144 if (found_item)
00145 return std::tr1::get<2>(*found_item);
00146 else
00147 return 0;
00148 }
00149
00150 bool
00151 debian_changes::get_value (key_type const& key,
00152 value_type& value) const
00153 {
00154 sbuild::log_debug(sbuild::DEBUG_INFO)
00155 << "Getting debian_changes key=" << key << std::endl;
00156 const item_type *found_item = find_item(key);
00157 if (found_item)
00158 {
00159 value_type const& val(std::tr1::get<1>(*found_item));
00160 value = val;
00161 return true;
00162 }
00163 sbuild::log_debug(sbuild::DEBUG_NOTICE)
00164 << "key not found" << std::endl;
00165 return false;
00166 }
00167
00168 bool
00169 debian_changes::get_value (key_type const& key,
00170 priority priority,
00171 value_type& value) const
00172 {
00173 bool status = get_value(key, value);
00174 check_priority(key, priority, status);
00175 return status;
00176 }
00177
00178 void
00179 debian_changes::set_value (key_type const& key,
00180 value_type const& value,
00181 size_type line)
00182 {
00183 item_map_type::iterator pos = items.find(key);
00184 if (pos != items.end())
00185 items.erase(pos);
00186 items.insert
00187 (item_map_type::value_type(key,
00188 item_type(key, value, line)));
00189 }
00190
00191 void
00192 debian_changes::remove_key (key_type const& key)
00193 {
00194 item_map_type::iterator pos = items.find(key);
00195 if (pos != items.end())
00196 items.erase(pos);
00197 }
00198
00199 debian_changes&
00200 debian_changes::operator += (debian_changes const& rhs)
00201 {
00202 for (item_map_type::const_iterator it = rhs.items.begin();
00203 it != rhs.items.end();
00204 ++it)
00205 {
00206 item_type const& item = it->second;
00207 key_type const& key(std::tr1::get<0>(item));
00208 value_type const& value(std::tr1::get<1>(item));
00209 size_type const& line(std::tr1::get<2>(item));
00210 set_value(key, value, line);
00211 }
00212
00213 return *this;
00214 }
00215
00216 debian_changes
00217 operator + (debian_changes const& lhs,
00218 debian_changes const& rhs)
00219 {
00220 debian_changes ret(lhs);
00221 ret += rhs;
00222 return ret;
00223 }
00224
00225 const debian_changes::item_type *
00226 debian_changes::find_item (key_type const& key) const
00227 {
00228 item_map_type::const_iterator pos = items.find(key);
00229 if (pos != items.end())
00230 return &pos->second;
00231
00232 return 0;
00233 }
00234
00235 debian_changes::item_type *
00236 debian_changes::find_item (key_type const& key)
00237 {
00238 item_map_type::iterator pos = items.find(key);
00239 if (pos != items.end())
00240 return &pos->second;
00241
00242 return 0;
00243 }
00244
00245 void
00246 debian_changes::check_priority (key_type const& key,
00247 priority priority,
00248 bool valid) const
00249 {
00250 if (valid == false)
00251 {
00252 size_type line = get_line(key);
00253
00254 switch (priority)
00255 {
00256 case PRIORITY_REQUIRED:
00257 {
00258 if (line)
00259 throw error(line, MISSING_KEY, key);
00260 else
00261 throw error(MISSING_KEY_NL, key);
00262 }
00263 break;
00264 default:
00265 break;
00266 }
00267 }
00268 else
00269 {
00270 size_type line = get_line(key);
00271
00272 switch (priority)
00273 {
00274 case PRIORITY_DEPRECATED:
00275 {
00276 if (line)
00277 {
00278 error e(line, DEPRECATED_KEY, key);
00279 e.set_reason(_("This option will be removed in the future"));
00280 log_exception_warning(e);
00281 }
00282 else
00283 {
00284 error e(DEPRECATED_KEY_NL, key);
00285 e.set_reason(_("This option will be removed in the future"));
00286 log_exception_warning(e);
00287 }
00288 }
00289 break;
00290 case PRIORITY_OBSOLETE:
00291 {
00292 if (line)
00293 {
00294 error e(line, OBSOLETE_KEY, key);
00295 e.set_reason(_("This option has been removed, and no longer has any effect"));
00296 log_exception_warning(e);
00297 }
00298 else
00299 {
00300 error e(OBSOLETE_KEY_NL, key);
00301 e.set_reason(_("This option has been removed, and no longer has any effect"));
00302 log_exception_warning(e);
00303 }
00304 }
00305 break;
00306 case PRIORITY_DISALLOWED:
00307 {
00308 if (line)
00309 throw error(line, DISALLOWED_KEY, key);
00310 else
00311 throw error(DISALLOWED_KEY_NL, key);
00312 }
00313 break;
00314 default:
00315 break;
00316 }
00317 }
00318 }