1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 
3  * Copyright (C) 2013 Red Hat, Inc.
4  *
5  * Licensed under the GNU Lesser General Public License Version 2.1
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <stdlib.h>
23 #include <fnmatch.h>
24 #include "dnf-reldep.h"
25 #include "dnf-sack-private.hpp"
26 #include "hy-subject.h"
27 #include "hy-iutil-private.hpp"
28 #include "nevra.hpp"
29 #include "nsvcap.hpp"
30 #include "hy-types.h"
31 #include "hy-query-private.hpp"
32 #include "hy-selector.h"
33 #include "hy-util-private.hpp"
34 #include "sack/query.hpp"
35 #include "sack/packageset.hpp"
36 
37 // most specific to least
38 const HyForm HY_FORMS_MOST_SPEC[] = {
39     HY_FORM_NEVRA, HY_FORM_NA, HY_FORM_NAME, HY_FORM_NEVR, HY_FORM_NEV, _HY_FORM_STOP_ };
40 
41 const HyModuleForm HY_MODULE_FORMS_MOST_SPEC[] = {
42         HY_MODULE_FORM_NSVCAP,
43         HY_MODULE_FORM_NSVCA,
44         HY_MODULE_FORM_NSVAP,
45         HY_MODULE_FORM_NSVA,
46         HY_MODULE_FORM_NSAP,
47         HY_MODULE_FORM_NSA,
48         HY_MODULE_FORM_NSVCP,
49         HY_MODULE_FORM_NSVP,
50         HY_MODULE_FORM_NSVC,
51         HY_MODULE_FORM_NSV,
52         HY_MODULE_FORM_NSP,
53         HY_MODULE_FORM_NS,
54         HY_MODULE_FORM_NAP,
55         HY_MODULE_FORM_NA,
56         HY_MODULE_FORM_NP,
57         HY_MODULE_FORM_N,
58         _HY_MODULE_FORM_STOP_};
59 
60 HySubject
hy_subject_create(const char * pattern)61 hy_subject_create(const char * pattern)
62 {
63     return g_strdup(pattern);
64 }
65 
66 void
hy_subject_free(HySubject subject)67 hy_subject_free(HySubject subject)
68 {
69     g_free(subject);
70 }
71 
72 /* Given a subject, attempt to create a query choose the first one, and update
73  * the query to try to match it.
74  *
75  * Since then, it was amended to add a `with_src` flag to avoid finding source packages
76  * from provides.
77  */
78 HyQuery
hy_subject_get_best_solution(HySubject subject,DnfSack * sack,HyForm * forms,HyNevra * out_nevra,gboolean icase,gboolean with_nevra,gboolean with_provides,gboolean with_filenames,gboolean with_src)79 hy_subject_get_best_solution(HySubject subject, DnfSack *sack, HyForm *forms, HyNevra *out_nevra,
80                              gboolean icase, gboolean with_nevra, gboolean with_provides,
81                              gboolean with_filenames, gboolean with_src)
82 {
83     std::unique_ptr<libdnf::Query> query(new libdnf::Query(sack, libdnf::Query::ExcludeFlags::APPLY_EXCLUDES));
84     if (!with_src)
85         query->addFilter(HY_PKG_ARCH, HY_NEQ, "src");
86     auto ret = query->filterSubject(subject, forms, icase, with_nevra, with_provides, with_filenames);
87     *out_nevra = ret.second.release();
88     return query.release();
89 }
90 
91 
92 HySelector
hy_subject_get_best_selector(HySubject subject,DnfSack * sack,HyForm * forms,bool obsoletes,const char * reponame)93 hy_subject_get_best_selector(HySubject subject, DnfSack *sack, HyForm *forms, bool obsoletes,
94     const char *reponame)
95 {
96     HyNevra nevra{nullptr};
97     HyQuery query = hy_subject_get_best_solution(subject, sack, forms, &nevra, FALSE, TRUE, TRUE,
98                                                  TRUE, false);
99     if (!hy_query_is_empty(query)) {
100         if (obsoletes && nevra && nevra->hasJustName()) {
101             DnfPackageSet *pset;
102             pset = hy_query_run_set(query);
103             HyQuery query_obsoletes = hy_query_clone(query);
104             hy_query_filter_package_in(query_obsoletes, HY_PKG_OBSOLETES, HY_EQ, pset);
105             delete pset;
106             hy_query_union(query, query_obsoletes);
107             hy_query_free(query_obsoletes);
108         }
109         if (reponame != NULL) {
110             HyQuery installed_query = hy_query_clone(query);
111             installed_query->installed();
112             hy_query_filter(query, HY_PKG_REPONAME, HY_EQ, reponame);
113             hy_query_union(query, installed_query);
114             hy_query_free(installed_query);
115         }
116     }
117     delete nevra;
118     HySelector selector = hy_query_to_selector(query);
119     hy_query_free(query);
120     return selector;
121 }
122