1 /*
2  * Copyright (C) 2017-2018 Red Hat, Inc.
3  *
4  * Licensed under the GNU Lesser General Public License Version 2.1
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #define HEXADECIMAL DIGITS "abcdef"
22 #define MODULE_SPECIAL "+._-"
23 #define GLOB "][*?!"
24 
25 #include "nsvcap.hpp"
26 
27 #include "libdnf/utils/utils.hpp"
28 
29 #include <regex/regex.hpp>
30 
31 namespace libdnf {
32 
33 #define MODULE_NAME "([" GLOB ASCII_LETTERS DIGITS MODULE_SPECIAL "]+)"
34 #define MODULE_STREAM MODULE_NAME
35 #define MODULE_VERSION "([" GLOB DIGITS "-]+)"
36 #define MODULE_CONTEXT MODULE_NAME
37 #define MODULE_ARCH MODULE_NAME
38 #define MODULE_PROFILE MODULE_NAME
39 
40 static const Regex NSVCAP_FORM_REGEX[]{
41     Regex("^" MODULE_NAME ":" MODULE_STREAM ":" MODULE_VERSION ":" MODULE_CONTEXT "::?" MODULE_ARCH "\\/"  MODULE_PROFILE "$", REG_EXTENDED),
42     Regex("^" MODULE_NAME ":" MODULE_STREAM ":" MODULE_VERSION ":" MODULE_CONTEXT "::?" MODULE_ARCH "\\/?" "()"           "$", REG_EXTENDED),
43     Regex("^" MODULE_NAME ":" MODULE_STREAM ":" MODULE_VERSION     "()"           "::"  MODULE_ARCH "\\/"  MODULE_PROFILE "$", REG_EXTENDED),
44     Regex("^" MODULE_NAME ":" MODULE_STREAM ":" MODULE_VERSION     "()"           "::"  MODULE_ARCH "\\/?" "()"           "$", REG_EXTENDED),
45     Regex("^" MODULE_NAME ":" MODULE_STREAM     "()"               "()"           "::"  MODULE_ARCH "\\/"  MODULE_PROFILE "$", REG_EXTENDED),
46     Regex("^" MODULE_NAME ":" MODULE_STREAM     "()"               "()"           "::"  MODULE_ARCH "\\/?" "()"           "$", REG_EXTENDED),
47     Regex("^" MODULE_NAME ":" MODULE_STREAM ":" MODULE_VERSION ":" MODULE_CONTEXT       "()"        "\\/"  MODULE_PROFILE "$", REG_EXTENDED),
48     Regex("^" MODULE_NAME ":" MODULE_STREAM ":" MODULE_VERSION     "()"                 "()"        "\\/"  MODULE_PROFILE "$", REG_EXTENDED),
49     Regex("^" MODULE_NAME ":" MODULE_STREAM ":" MODULE_VERSION ":" MODULE_CONTEXT       "()"        "\\/?" "()"           "$", REG_EXTENDED),
50     Regex("^" MODULE_NAME ":" MODULE_STREAM ":" MODULE_VERSION     "()"                 "()"        "\\/?" "()"           "$", REG_EXTENDED),
51     Regex("^" MODULE_NAME ":" MODULE_STREAM     "()"               "()"                 "()"        "\\/"  MODULE_PROFILE "$", REG_EXTENDED),
52     Regex("^" MODULE_NAME ":" MODULE_STREAM     "()"               "()"                 "()"        "\\/?" "()"           "$", REG_EXTENDED),
53     Regex("^" MODULE_NAME     "()"              "()"               "()"           "::"  MODULE_ARCH "\\/"  MODULE_PROFILE "$", REG_EXTENDED),
54     Regex("^" MODULE_NAME     "()"              "()"               "()"           "::"  MODULE_ARCH "\\/?" "()"           "$", REG_EXTENDED),
55     Regex("^" MODULE_NAME     "()"              "()"               "()"                 "()"        "\\/"  MODULE_PROFILE "$", REG_EXTENDED),
56     Regex("^" MODULE_NAME     "()"              "()"               "()"                 "()"        "\\/?" "()"           "$", REG_EXTENDED)
57 };
58 
parse(const char * nsvcapStr,HyModuleForm form)59 bool Nsvcap::parse(const char *nsvcapStr, HyModuleForm form)
60 {
61     enum { NAME = 1, STREAM = 2, VERSION = 3, CONTEXT = 4, ARCH = 5, PROFILE = 6, _LAST_ };
62     auto matchResult = NSVCAP_FORM_REGEX[form - 1].match(nsvcapStr, false, _LAST_);
63     if (!matchResult.isMatched() || matchResult.getMatchedLen(NAME) == 0)
64         return false;
65     name = matchResult.getMatchedString(NAME);
66     version = matchResult.getMatchedString(VERSION);
67     stream = matchResult.getMatchedString(STREAM);
68     context = matchResult.getMatchedString(CONTEXT);
69     arch = matchResult.getMatchedString(ARCH);
70     profile = matchResult.getMatchedString(PROFILE);
71     return true;
72 }
73 
74 void
clear()75 Nsvcap::clear()
76 {
77     name.clear();
78     stream.clear();
79     version.clear();
80     context.clear();
81     arch.clear();
82     profile.clear();
83 }
84 
85 }
86