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