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