| 1383 | } |
| 1384 | |
| 1385 | const Library::Container* Library::detectContainerInternal(const Token* const typeStart, DetectContainer detect, bool* isIterator, bool withoutStd) const |
| 1386 | { |
| 1387 | if (!typeStart) |
| 1388 | return nullptr; |
| 1389 | if (typeStart->isKeyword()) |
| 1390 | return nullptr; |
| 1391 | const Token* firstLinkedTok = nullptr; |
| 1392 | for (const Token* tok = typeStart; tok && !tok->varId(); tok = tok->next()) { |
| 1393 | if (!tok->link()) |
| 1394 | continue; |
| 1395 | |
| 1396 | firstLinkedTok = tok; |
| 1397 | break; |
| 1398 | } |
| 1399 | |
| 1400 | const bool hasScope = typeStart->strAt(1) == "::"; |
| 1401 | const bool bailIfHasStd = !withoutStd && !hasScope; |
| 1402 | |
| 1403 | for (const std::pair<const std::string, Library::Container> & c : mData->mContainers) { |
| 1404 | const Container& container = c.second; |
| 1405 | if (container.startPattern.empty()) |
| 1406 | continue; |
| 1407 | |
| 1408 | if (bailIfHasStd && container.startPatternHasStd) |
| 1409 | continue; |
| 1410 | |
| 1411 | const int offset = (withoutStd && container.startPatternHasStd) ? 7 : 0; |
| 1412 | |
| 1413 | // If endPattern is undefined, it will always match, but itEndPattern has to be defined. |
| 1414 | if (detect != IteratorOnly && container.endPattern.empty()) { |
| 1415 | if (!Token::Match(typeStart, container.startPattern2.c_str() + offset)) |
| 1416 | continue; |
| 1417 | |
| 1418 | if (isIterator) |
| 1419 | *isIterator = false; |
| 1420 | return &container; |
| 1421 | } |
| 1422 | |
| 1423 | if (!firstLinkedTok) |
| 1424 | continue; |
| 1425 | |
| 1426 | const bool matchedStartPattern = Token::Match(typeStart, container.startPattern2.c_str() + offset); |
| 1427 | if (!matchedStartPattern) |
| 1428 | continue; |
| 1429 | |
| 1430 | if (detect != ContainerOnly && Token::Match(firstLinkedTok->link(), container.itEndPattern.c_str())) { |
| 1431 | if (isIterator) |
| 1432 | *isIterator = true; |
| 1433 | return &container; |
| 1434 | } |
| 1435 | if (detect != IteratorOnly && Token::Match(firstLinkedTok->link(), container.endPattern.c_str())) { |
| 1436 | if (isIterator) |
| 1437 | *isIterator = false; |
| 1438 | return &container; |
| 1439 | } |
| 1440 | } |
| 1441 | return nullptr; |
| 1442 | } |