File indexing completed on 2024-05-19 05:40:59
0001 /*************************************************************************** 0002 * Copyright (C) 2014 by Renaud Guezennec * 0003 * https://rolisteam.org/contact * 0004 * * 0005 * This file is part of DiceParser * 0006 * * 0007 * DiceParser is free software; you can redistribute it and/or modify * 0008 * it under the terms of the GNU General Public License as published by * 0009 * the Free Software Foundation; either version 2 of the License, or * 0010 * (at your option) any later version. * 0011 * * 0012 * This program is distributed in the hope that it will be useful, * 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0015 * GNU General Public License for more details. * 0016 * * 0017 * You should have received a copy of the GNU General Public License * 0018 * along with this program; if not, write to the * 0019 * Free Software Foundation, Inc., * 0020 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0021 ***************************************************************************/ 0022 #include <QRegularExpression> 0023 #include <diceparser/dicealias.h> 0024 0025 #include <QDebug> 0026 0027 QString makeReplament(const QString& pattern, const QString& command, QString cmd) 0028 { 0029 auto hasPattern= cmd.contains(pattern); 0030 if(hasPattern) 0031 { 0032 auto idxPattern= cmd.indexOf(pattern); 0033 std::vector<std::pair<int, int>> quotes; 0034 0035 int pos= 0; 0036 bool open= true; 0037 while(pos != -1 && pos < cmd.size()) 0038 { 0039 auto oldPos= pos; 0040 pos= cmd.indexOf("\"", pos); 0041 if(open && pos != -1) 0042 open= false; 0043 else if(pos != -1) 0044 { 0045 quotes.push_back({oldPos, pos}); 0046 } 0047 0048 if(pos != -1) 0049 pos+= 1; 0050 } 0051 auto hasQuote= false; 0052 for(auto range : quotes) 0053 { 0054 if(idxPattern < range.second && idxPattern >= range.first) 0055 hasQuote= true; 0056 } 0057 0058 auto hasVariable= cmd.contains("${"); 0059 auto commentPos= cmd.lastIndexOf("#"); 0060 0061 if(!hasQuote && !hasVariable) 0062 { 0063 cmd.replace(pattern, command); 0064 } 0065 else 0066 { 0067 std::vector<int> patternPosList; 0068 std::vector<std::pair<int, int>> variablePos; 0069 0070 int pos= 0; 0071 QRegularExpressionMatch match; 0072 while(pos != -1) 0073 { 0074 auto start= cmd.indexOf(QRegularExpression("\\${\\N+}"), pos, &match); 0075 if(start >= 0) 0076 { 0077 auto end= start + match.captured().length(); 0078 variablePos.push_back(std::make_pair(start, end)); 0079 pos= end + 1; 0080 } 0081 else 0082 { 0083 pos= start; 0084 } 0085 } 0086 0087 pos= 0; 0088 while(pos != -1) 0089 { 0090 auto start= cmd.indexOf("\"", pos); 0091 if(start >= 0) 0092 { 0093 auto end= cmd.indexOf("\"", start + 1); 0094 variablePos.push_back(std::make_pair(start, end)); 0095 pos= end + 1; 0096 } 0097 else 0098 { 0099 pos= start; 0100 } 0101 } 0102 pos= 0; 0103 while((pos= cmd.indexOf(pattern, pos)) && pos != -1) 0104 { 0105 bool isInsidePair= false; 0106 for(auto pair : variablePos) 0107 { 0108 if(!isInsidePair) 0109 isInsidePair= (pos > pair.first && pos < pair.second); 0110 0111 if(commentPos >= 0 && pos > commentPos) 0112 isInsidePair= true; 0113 } 0114 if(!isInsidePair) 0115 patternPosList.push_back(pos); 0116 0117 pos+= 1; 0118 } 0119 0120 // TODO to be replace by C++14 when it is ready 0121 for(auto i= patternPosList.rbegin(); i != patternPosList.rend(); ++i) 0122 { 0123 cmd.replace(*i, 1, command); 0124 } 0125 } 0126 } 0127 return cmd; 0128 } 0129 0130 DiceAlias::DiceAlias(QString pattern, QString command, QString comment, bool isReplace, bool isEnable) 0131 : m_pattern(pattern) 0132 , m_command(command) 0133 , m_comment(comment) 0134 , m_type(isReplace ? REPLACE : REGEXP) 0135 , m_isEnable(isEnable) 0136 { 0137 } 0138 0139 DiceAlias::~DiceAlias() 0140 { 0141 // qDebug() << "destructeur of alias!" << this; 0142 } 0143 0144 DiceAlias::DiceAlias(const DiceAlias& alias) 0145 { 0146 m_command= alias.command(); 0147 m_comment= alias.comment(); 0148 m_pattern= alias.pattern(); 0149 m_isEnable= alias.isEnable(); 0150 m_type= alias.isReplace() ? REPLACE : REGEXP; 0151 } 0152 0153 bool DiceAlias::resolved(QString& str) 0154 { 0155 if(!m_isEnable) 0156 return false; 0157 0158 if((m_type == REPLACE) && (str.contains(m_pattern))) 0159 { 0160 str= makeReplament(m_pattern, m_command, str); 0161 return true; 0162 } 0163 else if(m_type == REGEXP) 0164 { 0165 QRegularExpression exp(m_pattern); 0166 str.replace(exp, m_command); 0167 return true; 0168 } 0169 return false; 0170 } 0171 0172 void DiceAlias::setCommand(QString command) 0173 { 0174 m_command= command; 0175 } 0176 0177 void DiceAlias::setPattern(const QString& pattern) 0178 { 0179 m_pattern= pattern; 0180 } 0181 0182 void DiceAlias::setType(RESOLUTION_TYPE type) 0183 { 0184 m_type= type; 0185 } 0186 QString DiceAlias::command() const 0187 { 0188 return m_command; 0189 } 0190 0191 QString DiceAlias::pattern() const 0192 { 0193 return m_pattern; 0194 } 0195 0196 bool DiceAlias::isReplace() const 0197 { 0198 return (m_type == REPLACE) ? true : false; 0199 } 0200 0201 void DiceAlias::setReplace(bool b) 0202 { 0203 if(b) 0204 { 0205 m_type= REPLACE; 0206 } 0207 else 0208 { 0209 m_type= REGEXP; 0210 } 0211 } 0212 0213 bool DiceAlias::isEnable() const 0214 { 0215 return m_isEnable; 0216 } 0217 0218 void DiceAlias::setEnable(bool b) 0219 { 0220 m_isEnable= b; 0221 } 0222 0223 QString DiceAlias::comment() const 0224 { 0225 return m_comment; 0226 } 0227 0228 void DiceAlias::setComment(const QString& comment) 0229 { 0230 m_comment= comment; 0231 }