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
00024 #include "zypp/source/susetags/PatternTagFileParser.h"
00025 #include <boost/regex.hpp>
00026
00027 #undef ZYPP_BASE_LOGGER_LOGGROUP
00028 #define ZYPP_BASE_LOGGER_LOGGROUP "PatternsTagFileParser"
00029
00030 using namespace std;
00031 using namespace boost;
00032
00034 namespace zypp
00035 {
00036
00037 namespace source
00038 {
00039
00040 namespace susetags
00041 {
00042
00043 Pattern::Ptr parsePattern( Source_Ref source_r, const Pathname & file_r )
00044 {
00045 MIL << "Starting to parse pattern " << file_r << std::endl;
00046 PatternTagFileParser p;
00047 try
00048 {
00049 p.parse( file_r );
00050 }
00051 catch(zypp::parser::tagfile::ParseException &e)
00052 {
00053 ZYPP_CAUGHT(e);
00054 ERR << "Pattern " << file_r << " is broken." << std::endl;
00055 return 0L;
00056 }
00057
00058 p.patImpl->_source = source_r;
00059 return p.result;
00060 }
00061
00062 PatternTagFileParser::PatternTagFileParser()
00063 {
00064 patImpl = new SuseTagsPatternImpl;
00065 }
00066
00067 void PatternTagFileParser::consume( const SingleTag &tag )
00068 {
00069 if ( tag.name == "Sum" )
00070 {
00071 patImpl->_summary.setText(tag.value, Locale(tag.modifier));
00072 }
00073 else if ( tag.name == "Ver" )
00074 {
00075 patImpl->_parser_version = tag.value;
00076 }
00077 else if ( tag.name == "Pat" )
00078 {
00079 std::string line = tag.value;
00080 std::vector<std::string> words;
00081
00082 if (str::split( line, std::back_inserter(words), " " ) != 4 )
00083 ZYPP_THROW( parser::tagfile::ParseException( "Expected [name version release arch] ], got [" + tag.value +"]") );
00084
00085 patImpl->_name = words[0];
00086 patImpl->_version = words[1];
00087 patImpl->_release = words[2];
00088 patImpl->_arch = words[3];
00089 }
00090 else if ( tag.name == "Vis" )
00091 {
00092 patImpl->_visible = (tag.value == "true") ? true : false;
00093 }
00094 else if ( tag.name == "Cat" )
00095 {
00096 patImpl->_category.setText(tag.value, Locale(tag.modifier));
00097 }
00098 else if ( tag.name == "Ico" )
00099 {
00100 patImpl->_icon = tag.value;
00101 }
00102 else if ( tag.name == "Ord" )
00103 {
00104 patImpl->_order = tag.value;
00105 }
00106 }
00107
00108 void PatternTagFileParser::consume( const MultiTag &tag )
00109 {
00110 if ( tag.name == "Des" )
00111 {
00112 std::string buffer;
00113 for (std::list<std::string>::const_iterator it = tag.values.begin(); it != tag.values.end(); ++it)
00114 {
00115 buffer += (*it + "\n");
00116 }
00117 patImpl->_description.setText(buffer, Locale(tag.modifier));
00118 }
00119 if ( tag.name == "Req" )
00120 {
00121 patImpl->_requires = tag.values;
00122 }
00123 else if ( tag.name == "Rec" )
00124 {
00125 patImpl->_recommends = tag.values;
00126 }
00127 else if ( tag.name == "Prv" )
00128 {
00129 patImpl->_provides = tag.values;
00130 }
00131 else if ( tag.name == "Obs" )
00132 {
00133 patImpl->_obsoletes = tag.values;
00134 }
00135 else if ( tag.name == "Con" )
00136 {
00137 patImpl->_conflicts = tag.values;
00138 }
00139 else if ( tag.name == "Sup" )
00140 {
00141 patImpl->_supplements = tag.values;
00142 }
00143 else if ( tag.name == "Sug" )
00144 {
00145 patImpl->_suggests = tag.values;
00146 }
00147 else if ( tag.name == "Fre" )
00148 {
00149 patImpl->_freshens = tag.values;
00150 }
00151 else if ( tag.name == "Prq" )
00152 {
00153 patImpl->_pkgrequires = tag.values;
00154 }
00155 else if ( tag.name == "Prc" )
00156 {
00157 patImpl->_pkgrecommends = tag.values;
00158 }
00159 else if ( tag.name == "Psg" )
00160 {
00161 patImpl->_pkgsuggests = tag.values;
00162 }
00163 }
00164
00165 static void parseDeps( const std::list<std::string> & strdeps, Dependencies & deps, Dep deptag, const Resolvable::Kind & kind = ResTraits<Pattern>::kind )
00166 {
00167 CapFactory f;
00168 for (std::list<std::string>::const_iterator it = strdeps.begin(); it != strdeps.end(); it++)
00169 {
00170 Capability cap = f.parse( kind, *it );
00171 deps[deptag].insert( cap );
00172 }
00173 return;
00174 }
00175
00176 void PatternTagFileParser::endParse()
00177 {
00178 #warning FIXME how to insert the specific language packages
00179 Dependencies _deps;
00180
00181 parseDeps( patImpl->_recommends, _deps, Dep::RECOMMENDS );
00182 parseDeps( patImpl->_requires, _deps, Dep::REQUIRES );
00183 parseDeps( patImpl->_conflicts, _deps, Dep::CONFLICTS );
00184 parseDeps( patImpl->_provides, _deps, Dep::PROVIDES );
00185 parseDeps( patImpl->_obsoletes, _deps, Dep::OBSOLETES );
00186 parseDeps( patImpl->_suggests, _deps, Dep::SUGGESTS );
00187 parseDeps( patImpl->_supplements, _deps, Dep::SUPPLEMENTS );
00188 parseDeps( patImpl->_freshens, _deps, Dep::FRESHENS );
00189 parseDeps( patImpl->_pkgrecommends, _deps, Dep::RECOMMENDS, ResTraits<Package>::kind );
00190 parseDeps( patImpl->_pkgrequires, _deps, Dep::REQUIRES, ResTraits<Package>::kind );
00191 parseDeps( patImpl->_pkgsuggests, _deps, Dep::SUGGESTS, ResTraits<Package>::kind );
00192
00193 Arch arch;
00194 if (!patImpl->_arch.empty())
00195 arch = Arch(patImpl->_arch);
00196
00197 NVRAD nvrad = NVRAD( patImpl->_name, Edition( patImpl->_version, patImpl->_release, std::string() ), arch, _deps );
00198 result = detail::makeResolvableFromImpl( nvrad, patImpl );
00199 }
00201 }
00204 }
00207 }