📄 profileevaluator.cpp
字号:
/******************************************************************************** Copyright (C) 2006-2006 Trolltech ASA. All rights reserved.**** This file is part of the Qt Linguist of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "profileevaluator.h"#include "proreader.h"#include <QtCore/QString>#include <QtCore/QSet>#include <QtCore/QRegExp>#include <QtCore/QByteArray>#include <QtCore/QFileInfo>#include <QtCore/QFile>#include <QtCore/QDir>#include "proparserutils.h"#ifdef Q_OS_UNIX#include <unistd.h>#endif#ifdef Q_OS_WIN32#define QT_POPEN _popen#else#define QT_POPEN popen#endifQStringList ProFileEvaluator::qmake_feature_paths(/*QMakeProperty *prop=0*/){ QStringList concat; { const QString base_concat = QDir::separator() + QString("features"); concat << base_concat + QDir::separator() + "mac"; concat << base_concat + QDir::separator() + "macx"; concat << base_concat + QDir::separator() + "unix"; concat << base_concat + QDir::separator() + "win32"; concat << base_concat + QDir::separator() + "mac9"; concat << base_concat + QDir::separator() + "qnx6"; concat << base_concat; } const QString mkspecs_concat = QDir::separator() + QString("mkspecs"); QStringList feature_roots; QByteArray mkspec_path = qgetenv("QMAKEFEATURES"); if(!mkspec_path.isNull()) feature_roots += splitPathList(QString::fromLocal8Bit(mkspec_path)); /* if(prop) feature_roots += splitPathList(prop->value("QMAKEFEATURES")); if(!Option::mkfile::cachefile.isEmpty()) { QString path; int last_slash = Option::mkfile::cachefile.lastIndexOf(Option::dir_sep); if(last_slash != -1) path = Option::fixPathToLocalOS(Option::mkfile::cachefile.left(last_slash)); for(QStringList::Iterator concat_it = concat.begin(); concat_it != concat.end(); ++concat_it) feature_roots << (path + (*concat_it)); } */ QByteArray qmakepath = qgetenv("QMAKEPATH"); if (!qmakepath.isNull()) { const QStringList lst = splitPathList(QString::fromLocal8Bit(qmakepath)); for(QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it) { for(QStringList::Iterator concat_it = concat.begin(); concat_it != concat.end(); ++concat_it) feature_roots << ((*it) + mkspecs_concat + (*concat_it)); } } //if(!Option::mkfile::qmakespec.isEmpty()) // feature_roots << Option::mkfile::qmakespec + QDir::separator() + "features"; //if(!Option::mkfile::qmakespec.isEmpty()) { // QFileInfo specfi(Option::mkfile::qmakespec); // QDir specdir(specfi.absoluteFilePath()); // while(!specdir.isRoot()) { // if(!specdir.cdUp() || specdir.isRoot()) // break; // if(QFile::exists(specdir.path() + QDir::separator() + "features")) { // for(QStringList::Iterator concat_it = concat.begin(); // concat_it != concat.end(); ++concat_it) // feature_roots << (specdir.path() + (*concat_it)); // break; // } // } //} for(QStringList::Iterator concat_it = concat.begin(); concat_it != concat.end(); ++concat_it) feature_roots << (propertyValue("QT_INSTALL_PREFIX") + mkspecs_concat + (*concat_it)); for(QStringList::Iterator concat_it = concat.begin(); concat_it != concat.end(); ++concat_it) feature_roots << (propertyValue("QT_INSTALL_DATA") + mkspecs_concat + (*concat_it)); return feature_roots;}ProFile *ProFileEvaluator::currentProFile() const{ if (m_profileStack.count() > 0) { return m_profileStack.top(); } return 0;}QString ProFileEvaluator::currentFileName() const{ ProFile *pro = currentProFile(); if (pro) return pro->fileName(); return QString();}QString ProFileEvaluator::getcwd() const{ ProFile *cur = m_profileStack.top(); QFileInfo fi(cur->fileName()); return fi.absolutePath();}ProFileEvaluator::ProFileEvaluator(){ Option::init();}ProFileEvaluator::~ProFileEvaluator(){}bool ProFileEvaluator::visitBeginProFile(ProFile * pro){ PRE(pro); bool ok = true; m_lineNo = pro->getLineNumber(); if (m_oldPath.isEmpty()) { // change the working directory for the initial profile we visit, since // that is *the* profile. All the other times we reach this function will be due to // include(file) or load(file) m_oldPath = QDir::currentPath(); m_profileStack.push(pro); QString fn = pro->fileName(); ok = QDir::setCurrent(QFileInfo(fn).absolutePath()); } if (m_origfile.isEmpty()) m_origfile = pro->fileName(); return ok;}bool ProFileEvaluator::visitEndProFile(ProFile * pro){ PRE(pro); bool ok = true; m_lineNo = pro->getLineNumber(); if (m_profileStack.count() == 1 && !m_oldPath.isEmpty()) { m_profileStack.pop(); ok = QDir::setCurrent(m_oldPath); } return ok;}bool ProFileEvaluator::visitProValue(ProValue *value){ PRE(value); m_lineNo = value->getLineNumber(); QString val(value->value()); QByteArray varName = m_lastVarName; QString v = expandVariableReferences(val); unquote(&v); switch (m_variableOperator) { case ProVariable::UniqueAddOperator: // * insertUnique(&m_valuemap, varName, v, true); break; case ProVariable::SetOperator: // = case ProVariable::AddOperator: // + insertUnique(&m_valuemap, varName, v, false); break; case ProVariable::RemoveOperator: // - break; case ProVariable::ReplaceOperator: // ~ { // DEFINES ~= s/a/b/?[gqi] QStringList vm = m_valuemap.value(varName); QChar sep = val.at(1); QStringList func = val.split(sep); if (func.count() < 3 || func.count() > 4) { logMessage(QString::fromAscii("~= operator (function s///) expects 3 or 4 arguments.\n"), MT_DebugLevel1); return false; } if (func[0] != QLatin1String("s")) { logMessage(QString::fromAscii("~= operator can only handle s/// function.\n"), MT_DebugLevel1); return false; } bool global = false, quote = false, case_sense = false; if (func.count() == 4) { global = func[3].indexOf('g') != -1; case_sense = func[3].indexOf('i') == -1; quote = func[3].indexOf('q') != -1; } QString pattern = func[1]; QString replace = func[2]; if(quote) pattern = QRegExp::escape(pattern); QRegExp regexp(pattern, case_sense ? Qt::CaseSensitive : Qt::CaseInsensitive); QStringList varlist = m_valuemap.value(varName); for(QStringList::Iterator varit = varlist.begin(); varit != varlist.end();) { if((*varit).contains(regexp)) { (*varit) = (*varit).replace(regexp, replace); if ((*varit).isEmpty()) varit = varlist.erase(varit); else ++varit; if(!global) break; } else ++varit; } } break; } return true;}bool ProFileEvaluator::visitProFunction(ProFunction *func){ m_lineNo = func->getLineNumber(); bool result = true; bool ok = true; QByteArray text = func->text(); int lparen = text.indexOf('('); int rparen = text.lastIndexOf(')'); Q_ASSERT(lparen < rparen); QString arguments(text.mid(lparen + 1, rparen - lparen - 1)); QByteArray funcName = text.left(lparen); ok &= evaluateConditionalFunction(funcName, arguments, &result); return ok;}bool ProFileEvaluator::visitBeginProBlock(ProBlock * block){ if (block->blockKind() == ProBlock::ScopeKind) { m_invertNext = false; m_condition = false; } return true;}bool ProFileEvaluator::visitEndProBlock(ProBlock * /*block*/){ return true;}bool ProFileEvaluator::visitBeginProVariable(ProVariable *variable){ m_lastVarName = variable->variable(); m_variableOperator = variable->variableOperator(); return true;}bool ProFileEvaluator::visitEndProVariable(ProVariable * /*variable*/){ m_lastVarName.clear(); return true;}bool ProFileEvaluator::visitProOperator(ProOperator * oper){ m_invertNext = (oper->operatorKind() == ProOperator::NotOperator); return true;}bool ProFileEvaluator::visitProCondition(ProCondition * cond){ if (!m_condition) { if (m_invertNext) { m_condition |= !isActiveConfig(cond->text(), true); } else { m_condition |= isActiveConfig(cond->text(), true); } } return true;}QString ProFileEvaluator::expandVariableReferences(const QString &str){ bool fOK; bool *ok = &fOK; QString ret; if(ok) *ok = true; if(str.isEmpty()) return ret; const ushort LSQUARE = '['; const ushort RSQUARE = ']'; const ushort LCURLY = '{'; const ushort RCURLY = '}'; const ushort LPAREN = '('; const ushort RPAREN = ')'; const ushort DOLLAR = '$'; const ushort SLASH = '\\'; const ushort UNDERSCORE = '_'; const ushort DOT = '.'; const ushort SPACE = ' '; const ushort TAB = '\t'; ushort unicode; const QChar *str_data = str.data(); const int str_len = str.length(); ushort term; QString var, args; int replaced = 0; QString current; for(int i = 0; i < str_len; ++i) { unicode = (str_data+i)->unicode(); const int start_var = i; if(unicode == SLASH) { bool escape = false; const char *symbols = "[]{}()$\\"; for(const char *s = symbols; *s; ++s) { if(*(str_data+i+1) == (ushort)*s) { i++; escape = true; if(!(replaced++)) current = str.left(start_var); current.append(str.at(i)); break; } } if(!escape && replaced) current.append(QChar(unicode)); continue; } if(unicode == SPACE || unicode == TAB) { unicode = 0; if(!current.isEmpty()) { ret.append(current); current.clear(); } } else if(unicode == DOLLAR && str_len > i+2) { unicode = (str_data+(++i))->unicode(); if(unicode == DOLLAR) { term = 0; var.clear(); args.clear(); enum { VAR, ENVIRON, FUNCTION, PROPERTY } var_type = VAR; unicode = (str_data+(++i))->unicode(); if(unicode == LSQUARE) { unicode = (str_data+(++i))->unicode(); term = RSQUARE; var_type = PROPERTY; } else if(unicode == LCURLY) { unicode = (str_data+(++i))->unicode(); var_type = VAR; term = RCURLY; } else if(unicode == LPAREN) { unicode = (str_data+(++i))->unicode(); var_type = ENVIRON; term = RPAREN; } while(1) { if(!(unicode & (0xFF<<8)) && unicode != DOT && unicode != UNDERSCORE && (unicode < 'a' || unicode > 'z') && (unicode < 'A' || unicode > 'Z') &&
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -