File indexing completed on 2024-05-05 16:46:17

0001 /*
0002     SPDX-FileCopyrightText: 2007 Andreas Pakulat <apaku@gmx.de>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "variablereferenceparser.h"
0008 
0009 bool isVarNameChar(QChar* c)
0010 {
0011     bool ret = c->isLetterOrNumber() || c->unicode() == '_';
0012     return ret;
0013 }
0014 
0015 VariableInfo::VariableInfo()
0016 {
0017 }
0018 
0019 VariableReferenceParser::VariableReferenceParser()
0020 {
0021 }
0022 
0023 void VariableReferenceParser::setContent(const QString& content)
0024 {
0025     m_content = content;
0026 }
0027 
0028 bool VariableReferenceParser::parse()
0029 {
0030     int size = m_content.size();
0031     int curpos = 0;
0032     if (size == 0 || size < 3) {
0033         return true;
0034     }
0035     QChar* it = m_content.data();
0036     do {
0037         if (it->unicode() == '$' && size > curpos + 2) {
0038             it++;
0039             curpos++;
0040             if (it->unicode() == '$') {
0041                 int begin = curpos - 1;
0042                 it++;
0043                 curpos++;
0044                 QString variable;
0045                 VariableInfo::VariableType type = VariableInfo::QMakeVariable;
0046                 if (it->unicode() == '(') {
0047                     do {
0048                         it++;
0049                         curpos++;
0050                     } while (curpos < size && it->unicode() != ')');
0051                     type = VariableInfo::ShellVariableResolveQMake;
0052                     variable = m_content.mid(begin + 3, curpos - begin - 3);
0053                     ++curpos;
0054                 } else if (it->unicode() == '{') {
0055                     do {
0056                         it++;
0057                         curpos++;
0058                         if (it->unicode() == '(') {
0059                             type = VariableInfo::FunctionCall;
0060                         }
0061                     } while (curpos < size && it->unicode() != '}');
0062                     variable = m_content.mid(begin + 3, curpos - begin - 3);
0063                     ++curpos;
0064                 } else if (it->unicode() == '[') {
0065                     do {
0066                         it++;
0067                         curpos++;
0068                     } while (curpos < size && it->unicode() != ']');
0069                     type = VariableInfo::QtConfigVariable;
0070                     variable = m_content.mid(begin + 3, curpos - begin - 3);
0071                     ++curpos;
0072                 } else {
0073                     do {
0074                         it++;
0075                         curpos++;
0076                     } while (curpos < size && isVarNameChar(it));
0077                     variable = m_content.mid(begin + 2, curpos - begin - 2);
0078 
0079                     if (it->unicode() == '(') {
0080                         type = VariableInfo::FunctionCall;
0081                         int braceCount = 0;
0082                         do {
0083                             it++;
0084                             curpos++;
0085                             if (it->unicode() == ')') {
0086                                 braceCount--;
0087                             } else if (it->unicode() == '(') {
0088                                 braceCount++;
0089                             }
0090                         } while (curpos < size && (it->unicode() != ')' || braceCount == 0));
0091                         // count the current position one further if we have it
0092                         // at the closing brace, this is needed for proper end-calculation
0093                         if (curpos < size && it->unicode() == ')') {
0094                             it++;
0095                             curpos++;
0096                         }
0097                     }
0098                 }
0099                 int end = curpos - 1;
0100                 appendPosition(variable, begin, end, type);
0101             } else if (it->unicode() == '(') {
0102                 int begin = curpos - 1;
0103                 do {
0104                     it++;
0105                     curpos++;
0106                 } while (curpos < size && it->unicode() != ')');
0107                 int end = curpos - 1;
0108                 appendPosition(m_content.mid(begin + 2, end - (begin + 2)), begin, end,
0109                                VariableInfo::ShellVariableResolveMake);
0110             }
0111         } else {
0112             curpos++;
0113         }
0114     } while (curpos < size);
0115     return true;
0116 }
0117 
0118 QStringList VariableReferenceParser::variableReferences() const
0119 {
0120     return m_variables.keys();
0121 }
0122 
0123 VariableInfo VariableReferenceParser::variableInfo(const QString& var) const
0124 {
0125     return m_variables.value(var, VariableInfo());
0126 }
0127 
0128 void VariableReferenceParser::appendPosition(const QString& var, int start, int end, VariableInfo::VariableType type)
0129 {
0130     auto variableIt = m_variables.find(var);
0131     if (variableIt == m_variables.end()) {
0132         VariableInfo vi;
0133         vi.type = type;
0134         variableIt = m_variables.insert(var, vi);
0135     }
0136     variableIt->positions << VariableInfo::Position(start, end);
0137 }