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