00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013 #include <fstream>
00014 #include <sstream>
00015
00016 #include <boost/tokenizer.hpp>
00017 #include <boost/algorithm/string.hpp>
00018
00019 #include "zypp/base/Logger.h"
00020 #include "zypp/base/PtrTypes.h"
00021 #include "zypp/base/String.h"
00022 #include "zypp/CapFactory.h"
00023 #include "zypp/ZYpp.h"
00024
00025 #include "zypp/source/susetags/SelectionTagFileParser.h"
00026 #include <boost/regex.hpp>
00027
00028 #undef ZYPP_BASE_LOGGER_LOGGROUP
00029 #define ZYPP_BASE_LOGGER_LOGGROUP "SelectionsTagFileParser"
00030
00031 using namespace std;
00032 using namespace boost;
00033
00035 namespace zypp
00036 {
00037
00038 namespace source
00039 {
00040
00041 namespace susetags
00042 {
00043
00044 Selection::Ptr parseSelection( Source_Ref source_r, const Pathname & file_r )
00045 {
00046 MIL << "Parsing selection " << file_r << " on source [" << source_r.alias() << "] at URL:[" << source_r.url().asString() << "]." << std::endl;
00047
00048 SelectionTagFileParser p;
00049 try
00050 {
00051 p.parse( file_r );
00052 }
00053 catch(zypp::parser::tagfile::ParseException &e)
00054 {
00055 ZYPP_CAUGHT(e);
00056 ERR << "Selection " << file_r << " on source [" << source_r.alias() << "] at URL:[" << source_r.url().asString() << "] is broken. Ignoring selection." << std::endl;
00057
00058 return 0L;
00059 }
00060
00061 p.selImpl->_source = source_r;
00062 return p.result;
00063
00064 }
00065
00066 SelectionTagFileParser::SelectionTagFileParser()
00067 {
00068 selImpl = new SuseTagsSelectionImpl;
00069 _locales = zypp::getZYpp()->getRequestedLocales();
00070 }
00071
00072 void SelectionTagFileParser::consume( const SingleTag &tag )
00073 {
00074
00075 if ( tag.name == "Sum" )
00076 {
00077 selImpl->_summary.setText(tag.value, Locale(tag.modifier));
00078 }
00079 else if ( tag.name == "Ver" )
00080 {
00081 selImpl->_parser_version = tag.value;
00082 }
00083 else if ( tag.name == "Sel" )
00084 {
00085 std::string line = tag.value;
00086 std::vector<std::string> words;
00087 str::split( line, std::back_inserter(words), " " );
00088
00089 switch ( words.size() )
00090 {
00091 case 4:
00092 selImpl->_name = words[0];
00093 selImpl->_version = words[1];
00094 selImpl->_release = words[2];
00095 selImpl->_arch = words[3];
00096 break;
00097 case 3:
00098 selImpl->_name = words[0];
00099 selImpl->_version = words[1];
00100 selImpl->_release = words[2];
00101 break;
00102 case 2:
00103 selImpl->_name = words[0];
00104 selImpl->_arch = words[1];
00105 break;
00106 case 1:
00107 selImpl->_name = words[0];
00108 break;
00109 default:
00110 ZYPP_THROW( parser::tagfile::ParseException( "Selection " + _file_r.asString() + ". Expected [name [version] [release] [arch] ], got [" + tag.value +"]"));
00111 break;
00112 }
00113 }
00114 else if ( tag.name == "Vis" )
00115 {
00116 selImpl->_visible = (tag.value == "true") ? true : false;
00117 }
00118 else if ( tag.name == "Cat" )
00119 {
00120 selImpl->_category = tag.value;
00121 }
00122 else if ( tag.name == "Ord" )
00123 {
00124 selImpl->_order = tag.value;
00125 }
00126 }
00127
00128 void SelectionTagFileParser::consume( const MultiTag &tag )
00129 {
00130 if ( tag.name == "Des" )
00131 {
00132 std::string buffer;
00133 for (std::list<std::string>::const_iterator it = tag.values.begin(); it != tag.values.end(); ++it)
00134 {
00135 buffer += (*it + "\n");
00136 }
00137 selImpl->_description.setText(buffer, Locale(tag.modifier));
00138 }
00139 if ( tag.name == "Req" )
00140 {
00141 selImpl->_requires.insert( tag.values.begin(), tag.values.end());
00142 }
00143 else if ( tag.name == "Rec" )
00144 {
00145 selImpl->_recommends.insert( tag.values.begin(), tag.values.end());
00146 }
00147 else if ( tag.name == "Prv" )
00148 {
00149 selImpl->_provides.insert( tag.values.begin(), tag.values.end());
00150 }
00151 else if ( tag.name == "Con" )
00152 {
00153 selImpl->_conflicts.insert( tag.values.begin(), tag.values.end());
00154 }
00155 else if ( tag.name == "Obs" )
00156 {
00157 selImpl->_obsoletes.insert( tag.values.begin(), tag.values.end());
00158 }
00159 else if ( tag.name == "Ins" )
00160 {
00161 selImpl->_inspacks[Locale(tag.modifier)].insert( tag.values.begin(), tag.values.end());
00162 }
00163 else if ( tag.name == "Del" )
00164 {
00165 selImpl->_delpacks[Locale(tag.modifier)].insert( tag.values.begin(), tag.values.end());
00166 }
00167 }
00168
00169 void SelectionTagFileParser::endParse()
00170 {
00171 #warning Dont do this language stuff in selections
00172 CapFactory _f;
00173 Dependencies _deps;
00174
00175
00176
00177 for (std::set<std::string>::const_iterator it = selImpl->_inspacks[Locale()].begin(); it != selImpl->_inspacks[Locale()].end(); it++)
00178 {
00179 Capability _cap = _f.parse( ResTraits<Package>::kind, *it);
00180 _deps[Dep::RECOMMENDS].insert(_cap);
00181 }
00182
00183
00184 for (ZYpp::LocaleSet::const_iterator loc = _locales.begin(); loc != _locales.end(); ++loc) {
00185 Locale l( *loc );
00186 std::set<std::string> locale_packs = selImpl->_inspacks[l];
00187 if (locale_packs.empty()) {
00188 l = Locale( l.language().code() );
00189 locale_packs = selImpl->_inspacks[l];
00190 }
00191 for (std::set<std::string>::const_iterator it = locale_packs.begin(); it != locale_packs.end(); it++)
00192 {
00193 Capability _cap = _f.parse( ResTraits<Package>::kind, *it);
00194 _deps[Dep::RECOMMENDS].insert(_cap);
00195 }
00196 }
00197
00198
00199
00200 for (std::set<std::string>::const_iterator it = selImpl->_delpacks[Locale()].begin(); it != selImpl->_delpacks[Locale()].end(); it++)
00201 {
00202 Capability _cap = _f.parse( ResTraits<Package>::kind, *it);
00203 _deps[Dep::OBSOLETES].insert(_cap);
00204 }
00205
00206
00207 #warning fallback to LanguageCode (i.e. en) if Locale (i.e. en_US) doesn't match
00208 for (ZYpp::LocaleSet::const_iterator loc = _locales.begin(); loc != _locales.end(); ++loc) {
00209 for (std::set<std::string>::const_iterator it = selImpl->_delpacks[*loc].begin(); it != selImpl->_delpacks[*loc].end(); it++)
00210 {
00211 Capability _cap = _f.parse( ResTraits<Package>::kind, *it);
00212 _deps[Dep::OBSOLETES].insert(_cap);
00213 }
00214 }
00215
00216
00217
00218 for (std::set<std::string>::const_iterator it = selImpl->_recommends.begin(); it != selImpl->_recommends.end(); it++)
00219 {
00220 Capability _cap = _f.parse( ResTraits<Selection>::kind, *it );
00221 _deps[Dep::RECOMMENDS].insert(_cap);
00222 }
00223
00224 for (std::set<std::string>::const_iterator it = selImpl->_requires.begin(); it != selImpl->_requires.end(); it++)
00225 {
00226 Capability _cap = _f.parse( ResTraits<Selection>::kind, *it );
00227 _deps[Dep::REQUIRES].insert(_cap);
00228 }
00229
00230 for (std::set<std::string>::const_iterator it = selImpl->_provides.begin(); it != selImpl->_provides.end(); it++)
00231 {
00232 Capability _cap = _f.parse( ResTraits<Selection>::kind, *it );
00233 _deps[Dep::PROVIDES].insert(_cap);
00234 }
00235
00236 for (std::set<std::string>::const_iterator it = selImpl->_conflicts.begin(); it != selImpl->_conflicts.end(); it++)
00237 {
00238 Capability _cap = _f.parse( ResTraits<Selection>::kind, *it );
00239 _deps[Dep::CONFLICTS].insert(_cap);
00240 }
00241
00242 for (std::set<std::string>::const_iterator it = selImpl->_obsoletes.begin(); it != selImpl->_obsoletes.end(); it++)
00243 {
00244 Capability _cap = _f.parse( ResTraits<Selection>::kind, *it );
00245 _deps[Dep::OBSOLETES].insert(_cap);
00246 }
00247 #warning: The set<string> dependencies are still kept in the selImpl but are not needed anymore
00248 Arch arch;
00249 Edition edition = Edition::noedition;
00250 if (!selImpl->_arch.empty())
00251 arch = Arch(selImpl->_arch);
00252
00253 if ( ! selImpl->_version.empty() )
00254 edition = Edition(selImpl->_version, selImpl->_release, std::string());
00255
00256 NVRAD nvrad = NVRAD( selImpl->_name, edition, arch, _deps );
00257 result = detail::makeResolvableFromImpl( nvrad, selImpl );
00258 }
00260 }
00263 }
00266 }