void EdgeSetIF::disconnectAll(IteratorId const iteratorId) { begin(iteratorId); while (hasNext(iteratorId)) { next(iteratorId)->disconnect(); } }
void EdgeSetIF::disconnectAll() { begin(); while (hasNext()) { next()->disconnect(); } }
bool EdgeArray::hasNext(Visibility const visibility) { return hasNext(this->edgeIterator, visibility); }
std::string show(const RegionDesc::Block& b) { std::string ret{"Block "}; folly::toAppend( b.func()->fullName()->data(), '@', b.start().offset(), " length ", b.length(), " initSpOff ", b.initialSpOffset(), '\n', &ret ); auto typePreds = makeMapWalker(b.typePreds()); auto byRefs = makeMapWalker(b.paramByRefs()); auto refPreds = makeMapWalker(b.reffinessPreds()); auto knownFuncs= makeMapWalker(b.knownFuncs()); auto skIter = b.start(); const Func* topFunc = nullptr; for (int i = 0; i < b.length(); ++i) { while (typePreds.hasNext(skIter)) { folly::toAppend(" predict: ", show(typePreds.next()), "\n", &ret); } while (refPreds.hasNext(skIter)) { folly::toAppend(" predict reffiness: ", show(refPreds.next()), "\n", &ret); } std::string knownFunc; if (knownFuncs.hasNext(skIter)) { topFunc = knownFuncs.next(); } if (topFunc) { const char* inlined = ""; if (i == b.length() - 1 && b.inlinedCallee()) { assert(topFunc == b.inlinedCallee()); inlined = " (call is inlined)"; } knownFunc = folly::format(" (top func: {}{})", topFunc->fullName()->data(), inlined).str(); } else { assert((i < b.length() - 1 || !b.inlinedCallee()) && "inlined FCall without a known funcd"); } std::string byRef; if (byRefs.hasNext(skIter)) { byRef = folly::format(" (passed by {})", byRefs.next() ? "reference" : "value").str(); } std::string instrString; folly::toAppend(instrToString((Op*)b.unit()->at(skIter.offset()), b.unit()), byRef, &instrString); folly::toAppend( " ", skIter.offset(), " ", knownFunc.empty() ? instrString : folly::format("{:<40}", instrString).str(), knownFunc, "\n", &ret ); skIter.advance(b.unit()); } for (const auto& postCond : b.postConds()) { folly::toAppend(" postcondition: ", show(postCond), "\n", &ret); } return ret; }
Type ExpressionBuilder::next() { if(!hasNext()) return Token_eof; return typeAt(i++); }
bool run(ASTNode* mainNode, RuntimeError* error, ExternalFunctions externals, char** libsToLoad, int libsCount) { assert(mainNode->nodeType == AST_MAIN); getValueFunc = getGetValueFuncPtr(); MemoryStack stack = makeMemoryStack(MEGABYTE(16)); Array<HINSTANCE> libraries = makeArray<HINSTANCE>(KILOBYTE(1)); Scope scalarTypesScope = makeScope(nullptr); Scope globalScope = makeScope(&scalarTypesScope); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s64"), {}, 8 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u64"), {}, 8 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("f64"), {}, 8 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s32"), {}, 4 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u32"), {}, 4 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("f32"), {}, 4 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s16"), {}, 2 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u16"), {}, 2 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("s8"), {}, 1 }); pushType(&scalarTypesScope, &stack, TypeDefinition{ makeSlice("u8"), {}, 1 }); ExternalArgumentDefinition binarys32Args[] = { { "a", "s32" }, { "b", "s32" } }; ExternalArgumentDefinition binaryf32Args[] = { { "a", "f32" }, { "b", "f32" } }; ExternalDefinition buildInExternals[] = { { &scalarS32FuncsHandler, "opAdd", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opSub", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opEqualsOrLess", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opEqualsOrsGreater", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opLess", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opGreater", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opEquals", "s32", binarys32Args, ArrayCount(binarys32Args) }, { &scalarS32FuncsHandler, "opNot", "s32", binarys32Args, ArrayCount(binarys32Args) }, }; loadExternals(&scalarTypesScope, &stack, ExternalFunctions{ buildInExternals, ArrayCount(buildInExternals) }); loadExternals(&scalarTypesScope, &stack, externals); loadLibrariries(&libraries, &scalarTypesScope, &stack, libsToLoad, libsCount); bool stillWorking = true; // load all global function and type definitions ListIterator<ASTNode> iterator = makeIterator(&mainNode->main.statements); while (stillWorking && hasNext(&iterator)) { ASTNode* statement = getNext(&iterator); if (statement->nodeType == AST_STATEMENT_FUNCTION_DEFINITION || statement->nodeType == AST_STATEMENT_TYPE_DEFINITION) stillWorking = runStatement(statement, &stack, &globalScope, error); else { // TODO: illigal statement exception? Or do this on parsing stage? } } if (stillWorking) { FunctionIdentifier mainIdentifier = {}; mainIdentifier.name = makeSlice("main"); Function* func = getFunction(&globalScope, mainIdentifier); if (func != nullptr) stillWorking = runStatement(func->body, &stack, &globalScope, error); else { stillWorking = false; *error = RuntimeError{ RET_UNDEFINED_FUNCTION, mainIdentifier.name, 0 }; } } scopeFreeMemory(&globalScope, &stack); scopeFreeMemory(&scalarTypesScope, &stack); freeAllLibraries(&libraries); freeArray(&libraries); freeMemoryStack(&stack); return stillWorking; }
bool EdgeArray::hasNext(IteratorId const iteratorId, Connectivity const connectivity, Visibility const visibility) { return hasNext(iteratorMap.at(iteratorId), connectivity, visibility); }
virtual ~CompositeIterator() { while (hasNext()) {} }
void Preprocessor::until(Token t) { while(hasNext() && next() != t) ; }
/** @return the next smallest number */ int next() { if (!hasNext()) return INT_MIN; int res = Q.front()->val; Q.pop(); return res; }
std::vector<std::string>* getNext() { assert(hasNext()); splitLine(); readLine(); return _cells.get(); }
char MaIterator::next() { SAFE_POINT(hasNext(), "Out of boundaries", U2Msa::INVALID_CHAR); return *(operator ++()); }
MaIterator &MaIterator::operator ++() { SAFE_POINT(hasNext(), "Out of boundaries", *this); position = getNextPosition(); SAFE_POINT(isInRange(position), "Out of boundaries", *this); return *this; }
//skip tokens and corresponding letters void U2AssemblyReadIterator::skipInsertion() { while(hasNext() && isInsertion()) { offsetInRead += cigar.at(offsetInCigar).count; offsetInCigar++; } }
//silently skip this tokens. void U2AssemblyReadIterator::skipPaddingAndHardClip() { while(hasNext() && isPaddingOrHardClip()) { offsetInCigar++; } }
void U2AssemblyReadIterator::skip() { while(hasNext() && !isMatch() && !isDeletion()) { skipInsertion(); skipPaddingAndHardClip(); } }
void CudaVideoRender::present(int effect){ if (hasNext()) { renderVideoFrame(m_bInterop); } }
ParsedPage HtmlApi::parsePage(Page *parentPage, const QString &source, int first, int limit) const { ParsedPage ret; // Getting tags if (contains("Regex/Tags")) { QList<Tag> tgs = Tag::FromRegexp(value("Regex/Tags"), source); if (!tgs.isEmpty()) { ret.tags = tgs; } } // Getting images QRegularExpression rxImages(value("Regex/Image"), QRegularExpression::DotMatchesEverythingOption); auto matches = rxImages.globalMatch(source); int id = 0; while (matches.hasNext()) { auto match = matches.next(); QMap<QString, QString> d = multiMatchToMap(match, rxImages.namedCaptureGroups()); // JSON elements if (d.contains("json") && !d["json"].isEmpty()) { QVariant src = Json::parse(d["json"]); if (!src.isNull()) { QMap<QString, QVariant> map = src.toMap(); for (auto it = map.begin(); it != map.end(); ++it) { d[it.key()] = it.value().toString(); } } } QSharedPointer<Image> img = parseImage(parentPage, d, id + first); if (!img.isNull()) { ret.images.append(img); } id++; } // Navigation if (contains("Regex/NextPage")) { QRegularExpression rxNextPage(value("Regex/NextPage")); auto match = rxNextPage.match(source); if (match.hasMatch()) { ret.urlNextPage = QUrl(match.captured(1)); } } if (contains("Regex/PrevPage")) { QRegularExpression rxPrevPage(value("Regex/PrevPage")); auto match = rxPrevPage.match(source); if (match.hasMatch()) { ret.urlPrevPage = QUrl(match.captured(1)); } } // Last page if (contains("LastPage")) { ret.pageCount = value("LastPage").toInt(); } else if (contains("Regex/LastPage")) { QRegularExpression rxlast(value("Regex/LastPage")); auto match = rxlast.match(source); int cnt = match.hasMatch() ? match.captured(1).remove(",").toInt() : 0; if (cnt > 0) { int pagesCount = cnt; if (value("Urls/Tags").contains("{pid}") || (contains("Urls/PagePart") && value("Urls/PagePart").contains("{pid}"))) { int forced = forcedLimit(); int ppid = forced > 0 ? forced : limit; pagesCount = qFloor(static_cast<qreal>(pagesCount) / static_cast<qreal>(ppid)) + 1; } ret.pageCount = pagesCount; } } // Count images if (contains("Regex/Count")) { QRegularExpression rxlast(value("Regex/Count")); auto match = rxlast.match(source); int cnt = match.hasMatch() ? match.captured(1).remove(",").toInt() : 0; if (cnt > 0) { ret.imageCount = cnt; } } // Wiki if (contains("Regex/Wiki")) { QRegularExpression rxwiki(value("Regex/Wiki"), QRegularExpression::DotMatchesEverythingOption); auto match = rxwiki.match(source); if (match.hasMatch()) { QString wiki = match.captured(1); wiki.remove("/wiki/show?title="); wiki.remove(QRegularExpression("<p><a href=\"([^\"]+)\">Full entry »</a></p>")); wiki.replace("<h6>", "<span class=\"title\">").replace("</h6>", "</span>"); ret.wiki = wiki; } } return ret; }
int64_t DataShared::getNextId(){ if(hasNext()){ return *m_iter++; } return -1; }
bool EdgeArray::hasNext() { return hasNext(this->edgeIterator); }
int next() { hasNext(); return (*start)[j++]; }
bool EdgeArray::hasNext(IteratorId const iteratorId) { return hasNext(iteratorMap.at(iteratorId)); }
void Moc::parse() { QList<NamespaceDef> namespaceList; bool templateClass = false; while (hasNext()) { Token t = next(); switch (t) { case NAMESPACE: { int rewind = index; if (test(IDENTIFIER)) { if (test(EQ)) { // namespace Foo = Bar::Baz; until(SEMIC); } else if (!test(SEMIC)) { NamespaceDef def; def.name = lexem(); next(LBRACE); def.begin = index - 1; until(RBRACE); def.end = index; index = def.begin + 1; namespaceList += def; index = rewind; } } break; } case SEMIC: case RBRACE: templateClass = false; break; case TEMPLATE: templateClass = true; break; case MOC_INCLUDE_BEGIN: currentFilenames.push(symbol().unquotedLexem()); break; case MOC_INCLUDE_END: currentFilenames.pop(); break; case Q_DECLARE_INTERFACE_TOKEN: parseDeclareInterface(); break; case Q_DECLARE_METATYPE_TOKEN: parseDeclareMetatype(); break; case USING: if (test(NAMESPACE)) { while (test(SCOPE) || test(IDENTIFIER)) ; next(SEMIC); } break; case CLASS: case STRUCT: { if (currentFilenames.size() <= 1) break; ClassDef def; if (!parseClassHead(&def)) continue; while (inClass(&def) && hasNext()) { if (next() == Q_OBJECT_TOKEN) { def.hasQObject = true; break; } } if (!def.hasQObject) continue; for (int i = namespaceList.size() - 1; i >= 0; --i) if (inNamespace(&namespaceList.at(i))) def.qualified.prepend(namespaceList.at(i).name + "::"); knownQObjectClasses.insert(def.classname); knownQObjectClasses.insert(def.qualified); continue; } default: break; } if ((t != CLASS && t != STRUCT)|| currentFilenames.size() > 1) continue; ClassDef def; if (parseClassHead(&def)) { FunctionDef::Access access = FunctionDef::Private; for (int i = namespaceList.size() - 1; i >= 0; --i) if (inNamespace(&namespaceList.at(i))) def.qualified.prepend(namespaceList.at(i).name + "::"); while (inClass(&def) && hasNext()) { switch ((t = next())) { case PRIVATE: access = FunctionDef::Private; if (test(Q_SIGNALS_TOKEN)) error("Signals cannot have access specifier"); break; case PROTECTED: access = FunctionDef::Protected; if (test(Q_SIGNALS_TOKEN)) error("Signals cannot have access specifier"); break; case PUBLIC: access = FunctionDef::Public; if (test(Q_SIGNALS_TOKEN)) error("Signals cannot have access specifier"); break; case CLASS: { ClassDef nestedDef; if (parseClassHead(&nestedDef)) { while (inClass(&nestedDef) && inClass(&def)) { t = next(); if (t >= Q_META_TOKEN_BEGIN && t < Q_META_TOKEN_END) error("Meta object features not supported for nested classes"); } } } break; case Q_SIGNALS_TOKEN: parseSignals(&def); break; case Q_SLOTS_TOKEN: switch (lookup(-1)) { case PUBLIC: case PROTECTED: case PRIVATE: parseSlots(&def, access); break; default: error("Missing access specifier for slots"); } break; case Q_OBJECT_TOKEN: def.hasQObject = true; if (templateClass) error("Template classes not supported by Q_OBJECT"); if (def.classname != "Qt" && def.classname != "QObject" && def.superclassList.isEmpty()) error("Class contains Q_OBJECT macro but does not inherit from QObject"); break; case Q_GADGET_TOKEN: def.hasQGadget = true; if (templateClass) error("Template classes not supported by Q_GADGET"); break; case Q_PROPERTY_TOKEN: parseProperty(&def); break; case Q_ENUMS_TOKEN: parseEnumOrFlag(&def, false); break; case Q_FLAGS_TOKEN: parseEnumOrFlag(&def, true); break; case Q_DECLARE_FLAGS_TOKEN: parseFlag(&def); break; case Q_CLASSINFO_TOKEN: parseClassInfo(&def); break; case Q_INTERFACES_TOKEN: parseInterfaces(&def); break; case Q_PRIVATE_SLOT_TOKEN: parseSlotInPrivate(&def, access); break; case ENUM: { EnumDef enumDef; if (parseEnum(&enumDef)) def.enumList += enumDef; } break; default: FunctionDef funcDef; funcDef.access = access; int rewind = index; if (parseMaybeFunction(&funcDef)) { if (access == FunctionDef::Public) def.publicList += funcDef; if (funcDef.isSlot) { def.slotList += funcDef; while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def.slotList += funcDef; } } else if (funcDef.isSignal) { def.signalList += funcDef; while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def.signalList += funcDef; } } else if (funcDef.isInvokable) { def.methodList += funcDef; while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) { funcDef.wasCloned = true; funcDef.arguments.removeLast(); def.methodList += funcDef; } } } else { index = rewind; } } } next(RBRACE); if (!def.hasQObject && def.signalList.isEmpty() && def.slotList.isEmpty() && def.propertyList.isEmpty() && def.enumDeclarations.isEmpty()) continue; // no meta object code required if (!def.hasQObject && !def.hasQGadget) error("Class declarations lacks Q_OBJECT macro."); checkSuperClasses(&def); classList += def; knownQObjectClasses.insert(def.classname); knownQObjectClasses.insert(def.qualified); } } }
void next() { if (hasNext()) prob(ni, nj); }
void* getNextData(Iterator* it){ ArrayList* list = it->list; if(!hasNext(it)) return NULL; return list->base[it->position++]; }
bool EdgeArray::hasNext(IteratorId const iteratorId, Visibility const visibility) { return hasNext(iteratorMap.at(iteratorId), visibility); }
void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) { currentFilenames.push(filename); preprocessed.reserve(preprocessed.size() + symbols.size()); while (hasNext()) { Token token = next(); switch (token) { case PP_INCLUDE: { int lineNum = symbol().lineNum; QByteArray include; bool local = false; if (test(PP_STRING_LITERAL)) { local = lexem().startsWith('\"'); include = unquotedLexem(); } else continue; until(PP_NEWLINE); // #### stringery QFileInfo fi; if (local) fi.setFile(QFileInfo(QString::fromLocal8Bit(filename)).dir(), QString::fromLocal8Bit(include)); for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) { const IncludePath &p = Preprocessor::includes.at(j); if (p.isFrameworkPath) { const int slashPos = include.indexOf('/'); if (slashPos == -1) continue; QByteArray frameworkCandidate = include.left(slashPos); frameworkCandidate.append(".framework/Headers/"); fi.setFile(QString::fromLocal8Bit(QByteArray(p.path + '/' + frameworkCandidate)), QString::fromLocal8Bit(include.mid(slashPos + 1))); } else { fi.setFile(QString::fromLocal8Bit(p.path), QString::fromLocal8Bit(include)); } // try again, maybe there's a file later in the include paths with the same name // (186067) if (fi.isDir()) { fi = QFileInfo(); continue; } } if (!fi.exists() || fi.isDir()) continue; include = fi.canonicalFilePath().toLocal8Bit(); if (Preprocessor::preprocessedIncludes.contains(include)) continue; Preprocessor::preprocessedIncludes.insert(include); QFile file(QString::fromLocal8Bit(include)); if (!file.open(QFile::ReadOnly)) continue; QByteArray input = file.readAll(); file.close(); if (input.isEmpty()) continue; Symbols saveSymbols = symbols; int saveIndex = index; // phase 1: get rid of backslash-newlines input = cleaned(input); // phase 2: tokenize for the preprocessor symbols = tokenize(input); input.clear(); index = 0; // phase 3: preprocess conditions and substitute macros preprocessed += Symbol(0, MOC_INCLUDE_BEGIN, include); preprocess(include, preprocessed); preprocessed += Symbol(lineNum, MOC_INCLUDE_END, include); symbols = saveSymbols; index = saveIndex; continue; } case PP_DEFINE: { next(IDENTIFIER); QByteArray name = lexem(); int start = index; until(PP_NEWLINE); Macro macro; macro.symbols.reserve(index - start - 1); for (int i = start; i < index - 1; ++i) macro.symbols += symbols.at(i); macros.insert(name, macro); continue; } case PP_UNDEF: { next(IDENTIFIER); QByteArray name = lexem(); until(PP_NEWLINE); macros.remove(name); continue; } case PP_IDENTIFIER: { // if (macros.contains(symbol())) // ; } // we _could_ easily substitute macros by the following // four lines, but we choose not to. /* if (macros.contains(sym.lexem())) { preprocessed += substitute(macros, symbols, i); continue; } */ break; case PP_HASH: until(PP_NEWLINE); continue; // skip unknown preprocessor statement case PP_IFDEF: case PP_IFNDEF: case PP_IF: while (!evaluateCondition()) { if (!skipBranch()) break; if (test(PP_ELIF)) { } else { until(PP_NEWLINE); break; } } continue; case PP_ELIF: case PP_ELSE: skipUntilEndif(); // fall through case PP_ENDIF: until(PP_NEWLINE); continue; case SIGNALS: case SLOTS: { Symbol sym = symbol(); if (macros.contains("QT_NO_KEYWORDS")) sym.token = IDENTIFIER; else sym.token = (token == SIGNALS ? Q_SIGNALS_TOKEN : Q_SLOTS_TOKEN); preprocessed += sym; } continue; default: break; } preprocessed += symbol(); } currentFilenames.pop(); }
bool EdgeArray::hasNext(Connectivity const connectivity, Visibility const visibility) { return hasNext(this->edgeIterator, connectivity, visibility); }
void OsmAnd::ObfsCollection_P::collectSources() const { QWriteLocker scopedLocker1(&_collectedSourcesLock); QReadLocker scopedLocker2(&_sourcesOriginsLock); // Capture how many invalidations are going to be processed const auto invalidationsToProcess = _collectedSourcesInvalidated.loadAcquire(); if (invalidationsToProcess == 0) return; #if OSMAND_DEBUG const auto collectSources_Begin = std::chrono::high_resolution_clock::now(); #endif // Check all previously collected sources auto itCollectedSourcesEntry = mutableIteratorOf(_collectedSources); while(itCollectedSourcesEntry.hasNext()) { const auto& collectedSourcesEntry = itCollectedSourcesEntry.next(); const auto& originId = collectedSourcesEntry.key(); auto& collectedSources = collectedSourcesEntry.value(); const auto& itSourceOrigin = _sourcesOrigins.constFind(originId); // If current source origin was removed, // remove entire each collected source related to it if (itSourceOrigin == _sourcesOrigins.cend()) { // Ensure that ObfFile is not being read anywhere for(const auto& itCollectedSource : rangeOf(collectedSources)) { const auto obfFile = itCollectedSource.value(); //NOTE: OBF should have been locked here, but since file is gone anyways, this lock is quite useless itCollectedSource.value().reset(); assert(obfFile.use_count() == 1); } itCollectedSourcesEntry.remove(); continue; } // Check for missing files auto itObfFileEntry = mutableIteratorOf(collectedSources); while(itObfFileEntry.hasNext()) { const auto& sourceFilename = itObfFileEntry.next().key(); if (QFile::exists(sourceFilename)) continue; const auto obfFile = itObfFileEntry.value(); //NOTE: OBF should have been locked here, but since file is gone anyways, this lock is quite useless itObfFileEntry.remove(); assert(obfFile.use_count() == 1); } // If all collected sources for current source origin are gone, // remove entire collection attached to source origin ID if (collectedSources.isEmpty()) { itCollectedSourcesEntry.remove(); continue; } } // Find all files uncollected sources for(const auto& itEntry : rangeOf(constOf(_sourcesOrigins))) { const auto& originId = itEntry.key(); const auto& entry = itEntry.value(); auto itCollectedSources = _collectedSources.find(originId); if (itCollectedSources == _collectedSources.end()) itCollectedSources = _collectedSources.insert(originId, QHash<QString, std::shared_ptr<ObfFile> >()); auto& collectedSources = *itCollectedSources; if (entry->type == SourceOriginType::Directory) { const auto& directoryAsSourceOrigin = std::static_pointer_cast<const DirectoryAsSourceOrigin>(entry); QFileInfoList obfFilesInfo; Utilities::findFiles(directoryAsSourceOrigin->directory, QStringList() << QLatin1String("*.obf"), obfFilesInfo, directoryAsSourceOrigin->isRecursive); for(const auto& obfFileInfo : constOf(obfFilesInfo)) { const auto& obfFilePath = obfFileInfo.canonicalFilePath(); if (collectedSources.constFind(obfFilePath) != collectedSources.cend()) continue; auto obfFile = new ObfFile(obfFilePath, obfFileInfo.size()); collectedSources.insert(obfFilePath, std::shared_ptr<ObfFile>(obfFile)); } if (directoryAsSourceOrigin->isRecursive) { QFileInfoList directoriesInfo; Utilities::findDirectories(directoryAsSourceOrigin->directory, QStringList() << QLatin1String("*"), directoriesInfo, true); for(const auto& directoryInfo : constOf(directoriesInfo)) { const auto canonicalPath = directoryInfo.canonicalFilePath(); if (directoryAsSourceOrigin->watchedSubdirectories.contains(canonicalPath)) continue; _fileSystemWatcher->addPath(canonicalPath); directoryAsSourceOrigin->watchedSubdirectories.insert(canonicalPath); } } } else if (entry->type == SourceOriginType::File) { const auto& fileAsSourceOrigin = std::static_pointer_cast<const FileAsSourceOrigin>(entry); if (!fileAsSourceOrigin->fileInfo.exists()) continue; const auto& obfFilePath = fileAsSourceOrigin->fileInfo.canonicalFilePath(); if (collectedSources.constFind(obfFilePath) != collectedSources.cend()) continue; auto obfFile = new ObfFile(obfFilePath, fileAsSourceOrigin->fileInfo.size()); collectedSources.insert(obfFilePath, std::shared_ptr<ObfFile>(obfFile)); } } // Decrement invalidations counter with number of processed onces _collectedSourcesInvalidated.fetchAndAddOrdered(-invalidationsToProcess); #if OSMAND_DEBUG const auto collectSources_End = std::chrono::high_resolution_clock::now(); const std::chrono::duration<float> collectSources_Elapsed = collectSources_End - collectSources_Begin; LogPrintf(LogSeverityLevel::Info, "Collected OBF sources in %fs", collectSources_Elapsed.count()); #endif }
static bool runStatement(ASTNode* node, MemoryStack* stack, Scope* scope, RuntimeError* error) { switch (node->nodeType) { case AST_STATEMENT_TYPE_DEFINITION: { if (getTypeDefinition(scope, node->typeDefinition.identifier, false)) { *error = RuntimeError{ RET_TYPE_ALREADY_DEFINED, node->typeDefinition.identifier, node->typeDefinition.lineNumber }; return false; } else { TypeDefinition* typeDef = scopePushToList(scope, stack, &scope->types); typeDef->identifier = node->typeDefinition.identifier; typeDef->members = {}; ListIterator<ASTNode> iterator = makeIterator(&node->typeDefinition.definitions); int currOffsetInBytes = 0; while (hasNext(&iterator)) { ASTNode* node = getNext(&iterator); StructMember* member = scopePushToList(scope, stack, &typeDef->members); member->identifier = node->variableDeclaration.identifier; member->type = makeType(scope, node->variableDeclaration.typeIdentifier); member->offsetInBytes = currOffsetInBytes; currOffsetInBytes += member->type.definition->totalSizeInBytes; } typeDef->totalSizeInBytes = currOffsetInBytes; return true; } } break; case AST_STATEMENT_VARIABLE_DECLARATION: { if (getVariable(scope, node->variableDeclaration.identifier, false)) { *error = RuntimeError{ RET_VARIABLE_ALREADY_DEFINED, node->variableDeclaration.identifier, node->variableDeclaration.lineNumber }; return false; } else { Variable* var = defineAVariable( node->variableDeclaration.identifier, makeType(scope, node->variableDeclaration.typeIdentifier), stack, scope); if (node->variableDeclaration.expression) return runExpression(node->variableDeclaration.expression, stack, scope, error, &var->value); else return true; // TODO: set default value } } break; case AST_STATEMENT_FUNCTION_DEFINITION: { Function func; func.type = FT_INTERNAL; func.identifier.name = node->functionDefinition.identifier; func.identifier.arguments = {}; bool stillWorking = true; if (!node->functionDefinition.returnType) func.returnType = Type{ nullptr, 0 }; else { func.returnType = makeType(scope, node->functionDefinition.returnType); if (!func.returnType.definition) { *error = RuntimeError{ RET_UNDEFINED_TYPE, node->functionDefinition.returnType->typeIdentifier.name, node->functionDefinition.lineNumber }; stillWorking = false; } } ListIterator<ASTNode> args = makeIterator(&node->functionDefinition.arguments); while (stillWorking && hasNext(&args)) { ASTNode* arg = getNext(&args); Argument* argument = scopePushToList(scope, stack, &func.identifier.arguments); argument->identifier = arg->variableDeclaration.identifier; argument->type = makeType(scope, arg->variableDeclaration.typeIdentifier); if (!argument->type.definition) { *error = RuntimeError{ RET_UNDEFINED_TYPE, arg->variableDeclaration.typeIdentifier->typeIdentifier.name, arg->variableDeclaration.lineNumber }; stillWorking = false; } } func.body = node->functionDefinition.body; Function* hasFunc = getFunction(scope, func.identifier, false); if (hasFunc) { *error = RuntimeError{ RET_FUNCTION_ALREADY_DEFINED, node->functionDefinition.identifier, node->functionDefinition.lineNumber }; stillWorking = false; } else { *scopePushToList(scope, stack, &scope->functions) = func; } return stillWorking; } break; case AST_STATEMENT_IF: { Scope ifScope = makeScope(scope); Value conditionResult = pushValue(&ifScope, stack, Type{ getTypeDefinition(scope, makeSlice("s32")), false }); bool stillWorking = runExpression(node->ifStatement.condition, stack, scope, error, &conditionResult); if (stillWorking) { if (*(int*)conditionResult.memory != 0) { stillWorking = runStatement(node->ifStatement.ifCase, stack, &ifScope, error); } else if (node->ifStatement.elseCase != nullptr) { stillWorking = runStatement(node->ifStatement.elseCase, stack, &ifScope, error); } } scopeFreeMemory(&ifScope, stack); return stillWorking; } break; case AST_STATEMENT_WHILE: { Scope whileScope = makeScope(scope); Value conditionResult = pushValue(&whileScope, stack, Type{ getTypeDefinition(scope, makeSlice("s32")), false }); bool stillWorking = runExpression(node->whileStatement.condition, stack, scope, error, &conditionResult); if (stillWorking) { while (*(int*)conditionResult.memory != 0) { if (!(stillWorking = runStatement(node->whileStatement.body, stack, &whileScope, error))) break; if (!(stillWorking = runExpression(node->whileStatement.condition, stack, scope, error, &conditionResult))) break; } } scopeFreeMemory(&whileScope, stack); return stillWorking; } break; case AST_STATEMENT_ASSIGNMENT: { Value value; if (getValue(scope, node->assignment.lValue, error, &value)) { return runExpression(node->assignment.expression, stack, scope, error, &value); } else return false; } break; case AST_STATEMENTS_BLOCK: { Scope blockScope = makeScope(scope); bool result = runStatements(&node->statementsBlock.statements, stack, &blockScope, error); scopeFreeMemory(&blockScope, stack); return result; } break; case AST_FUNCTION_CALL: { return runFunctionCall(node, stack, scope, error, nullptr); } break; default: { assert(!"this is not a statement!"); return false; } break; } }