1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #include "CMDLineRegistry.h"
23 
24 #include "CMDLineCoreOptions.h"
25 #include "CMDLineHelpProvider.h"
26 
27 namespace U2 {
28 
29 /***************************************************
30  * CMDLineRegistry
31  ***************************************************/
32 const QString CMDLineRegistry::PLUGINS_ARG = "plugins";
33 const QString CMDLineRegistry::VERIFY_ARG = "verify";
34 
35 const QString SINGLE_DASH = "-";
36 const QString DOUBLE_DASH = "--";
37 const QString EQUALS = "=";
38 
isDoubleDashParameter(const QString & val)39 static bool isDoubleDashParameter(const QString &val) {
40     return val.startsWith(DOUBLE_DASH) && val.length() > 2 && val.at(2).isLetter();
41 }
42 
isSingleDashParameter(const QString & val)43 static bool isSingleDashParameter(const QString &val) {
44     return val.startsWith(SINGLE_DASH) && val.length() > 1 && val.at(1).isLetter();
45 }
46 
tryParseDoubleDashParameter(const QString & argument,QString & paramName,QString & paramValue)47 static bool tryParseDoubleDashParameter(const QString &argument, QString &paramName, QString &paramValue) {
48     if (!isDoubleDashParameter(argument)) {
49         return false;
50     }
51     int nameEndIdx = argument.indexOf(EQUALS);
52     if (nameEndIdx == -1) {
53         paramName = argument.mid(2);
54     } else {
55         paramName = argument.mid(2, nameEndIdx - 2);
56         paramValue = argument.mid(nameEndIdx + 1);
57     }
58     return true;
59 }
60 
tryParseSingleDashParameter(const QString & argument,const QString & nextArgument,QString & paramName,QString & paramValue)61 static bool tryParseSingleDashParameter(const QString &argument, const QString &nextArgument, QString &paramName, QString &paramValue) {
62     if (!isSingleDashParameter(argument)) {
63         return false;
64     }
65     paramName = argument.mid(1);
66     if (!isDoubleDashParameter(nextArgument) && !isSingleDashParameter(nextArgument)) {
67         paramValue = nextArgument;
68     }
69     return true;
70 }
71 
CMDLineRegistry(const QStringList & arguments)72 CMDLineRegistry::CMDLineRegistry(const QStringList &arguments) {
73     int sz = arguments.size();
74     for (int i = 0; i < sz; i++) {
75         const QString &argument = arguments.at(i);
76         StrStrPair pair;
77         if (!tryParseDoubleDashParameter(argument, pair.first, pair.second)) {
78             QString nextArgument;
79             if (i < sz - 1) {
80                 nextArgument = arguments.at(i + 1);
81             }
82             if (tryParseSingleDashParameter(argument, nextArgument, pair.first, pair.second)) {
83                 if (!pair.second.isEmpty()) {
84                     i++;
85                 }
86             } else {
87                 pair.second = argument;
88             }
89         }
90         if (pair.second.length() > 1) {
91             if (pair.second.startsWith("\"") && pair.second.endsWith("\"")) {
92                 pair.second = pair.second.mid(1, pair.second.length() - 2);
93             }
94         }
95         params << pair;
96     }
97 }
98 
~CMDLineRegistry()99 CMDLineRegistry::~CMDLineRegistry() {
100     qDeleteAll(helpProviders);
101 }
102 
getParameters() const103 const QList<StrStrPair> &CMDLineRegistry::getParameters() const {
104     return params;
105 }
106 
getOrderedParameterNames() const107 QStringList CMDLineRegistry::getOrderedParameterNames() const {
108     QStringList res;
109     QList<StrStrPair>::const_iterator it = params.constBegin();
110     while (it != params.constEnd()) {
111         res << it->first;
112         ++it;
113     }
114     return res;
115 }
116 
hasParameter(const QString & paramName,int startWithIdx) const117 bool CMDLineRegistry::hasParameter(const QString &paramName, int startWithIdx) const {
118     int sz = params.size();
119     for (int i = qMax(0, startWithIdx); i < sz; ++i) {
120         const StrStrPair &param = params[i];
121         if (param.first == paramName) {
122             return true;
123         }
124     }
125     return false;
126 }
127 
getParameterValue(const QString & paramName,int startWithIdx) const128 QString CMDLineRegistry::getParameterValue(const QString &paramName, int startWithIdx) const {
129     int sz = params.size();
130     for (int i = qMax(0, startWithIdx); i < sz; ++i) {
131         const StrStrPair &param = params[i];
132         if (param.first == paramName) {
133             return param.second;
134         }
135     }
136     return QString();
137 }
138 
providerNameComparator(const CMDLineHelpProvider * p1,const CMDLineHelpProvider * p2)139 static bool providerNameComparator(const CMDLineHelpProvider *p1, const CMDLineHelpProvider *p2) {
140     return p1->getHelpSectionFullName().compare(p2->getHelpSectionFullName()) > 0;
141 }
142 
registerCMDLineHelpProvider(CMDLineHelpProvider * provider)143 void CMDLineRegistry::registerCMDLineHelpProvider(CMDLineHelpProvider *provider) {
144     helpProviders.append(provider);
145     std::stable_sort(helpProviders.begin(), helpProviders.end(), providerNameComparator);
146 }
147 
unregisterCMDLineHelpProvider(CMDLineHelpProvider * provider)148 void CMDLineRegistry::unregisterCMDLineHelpProvider(CMDLineHelpProvider *provider) {
149     helpProviders.removeOne(provider);
150 }
151 
152 }  // namespace U2
153