File: solvable-matcher.cc

package info (click to toggle)
snapper 0.10.6-1.2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,072 kB
  • sloc: cpp: 24,846; ansic: 1,466; sh: 1,410; makefile: 514; python: 127; ruby: 90
file content (117 lines) | stat: -rw-r--r-- 2,862 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
 * Copyright (c) [2019-2023] SUSE LLC
 *
 * All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, contact SUSE LLC.
 *
 * To contact SUSE about this file by physical or electronic mail, you may
 * find current contact information at www.suse.com.
 */


#include "solvable-matcher.h"

#include <fnmatch.h>
#include <regex>
#include "snapper/XmlFile.h"
#include "snapper/Log.h"

using namespace std;
using namespace snapper;


bool
SolvableMatcher::match(const string& solvable) const
{
    y2deb("match '" << solvable << "' by " << (kind == Kind::GLOB ? "GLOB '": "REGEX '") << pattern << '\'');

    bool res = false;

    switch (kind)
    {
	case Kind::GLOB:
	{
	    static const int flags = 0;
	    res = fnmatch(pattern.c_str(), solvable.c_str(), flags) == 0;
	}
	break;

	case Kind::REGEX:
	{
	    try
	    {
		// POSIX Extended Regular Expression Syntax
		// The original Python implementation allows "foo" to match "foo-devel"
		const regex rx_pattern("^" + pattern, regex::extended);
		res = regex_search(solvable, rx_pattern);
	    }
	    catch (const regex_error& e)
	    {
		y2err("Regex compilation error:" << e.what() << + " pattern:'" << pattern << "'");
	    }
	}
	break;
    }

    y2deb("-> " << res);
    return res;
}


vector<SolvableMatcher>
SolvableMatcher::load_config(const string& cfg_filename)
{
    y2deb("parsing " << cfg_filename);

    vector<SolvableMatcher> result;

    try
    {
	XmlFile config(cfg_filename);

	const xmlNode* root = config.getRootElement();
	const xmlNode* solvables_n = getChildNode(root, "solvables");
	const vector<const xmlNode*> solvables_l = getChildNodes(solvables_n, "solvable");
	for (const xmlNode* node : solvables_l)
	{
	    string pattern;
	    getValue(node, pattern);

	    Kind kind;
	    string kind_s;
	    getAttributeValue(node, "match", kind_s);
	    if (kind_s == "w")		// w = Wildcard
		kind = Kind::GLOB;
	    else if (kind_s == "re")	// re = Regular Expression
		kind = Kind::REGEX;
	    else
	    {
		y2err("Unknown match attribute '" << kind_s << "', disregarding pattern '" <<
		      pattern << "'");
		continue;
	    }

	    bool important = false;
	    getAttributeValue(node, "important", important);

	    result.emplace_back(pattern, kind, important);
	}
    }
    catch (const exception& e)
    {
	y2err("Loading XML failed");
    }

    return result;
}