File indexing completed on 2024-05-05 05:51:39

0001 /***************************************************************************
0002  *   SPDX-FileCopyrightText: 2004 Jens Dagerbo *
0003  *   jens.dagerbo@swipnet.se                                               *
0004  *                                                                         *
0005  *   SPDX-License-Identifier: GPL-2.0-or-later
0006  *                                                                         *
0007  ***************************************************************************/
0008 #include "tags.h"
0009 #include <stdio.h>
0010 
0011 namespace ctags
0012 {
0013 #include "readtags.h"
0014 }
0015 
0016 #include "ctagskinds.h"
0017 
0018 QString Tags::_tagsfile;
0019 
0020 Tags::TagEntry::TagEntry()
0021 {
0022 }
0023 
0024 Tags::TagEntry::TagEntry(const QString &tag, const QString &type, const QString &file, const QString &pattern)
0025     : tag(tag)
0026     , type(type)
0027     , file(file)
0028     , pattern(pattern)
0029 {
0030 }
0031 
0032 bool Tags::hasTag(const QString &tag)
0033 {
0034     ctags::tagFileInfo info;
0035     ctags::tagFile *file = ctags::tagsOpen(_tagsfile.toLocal8Bit().constData(), &info);
0036     ctags::tagEntry entry;
0037 
0038     bool found = (ctags::tagsFind(file, &entry, tag.toLocal8Bit().constData(), TAG_FULLMATCH | TAG_OBSERVECASE) == ctags::TagSuccess);
0039 
0040     ctags::tagsClose(file);
0041 
0042     return found;
0043 }
0044 
0045 bool Tags::hasTag(const QString &fileName, const QString &tag)
0046 {
0047     setTagsFile(fileName);
0048     ctags::tagFileInfo info;
0049     ctags::tagFile *file = ctags::tagsOpen(_tagsfile.toLocal8Bit().constData(), &info);
0050     ctags::tagEntry entry;
0051 
0052     bool found = (ctags::tagsFind(file, &entry, tag.toLocal8Bit().constData(), TAG_FULLMATCH | TAG_OBSERVECASE) == ctags::TagSuccess);
0053 
0054     ctags::tagsClose(file);
0055 
0056     return found;
0057 }
0058 
0059 unsigned int Tags::numberOfMatches(const QString &tagpart, bool partial)
0060 {
0061     unsigned int n = 0;
0062 
0063     if (tagpart.isEmpty()) {
0064         return 0;
0065     }
0066 
0067     ctags::tagFileInfo info;
0068     ctags::tagFile *file = ctags::tagsOpen(_tagsfile.toLocal8Bit().constData(), &info);
0069     ctags::tagEntry entry;
0070 
0071     QByteArray tagpartBArray = tagpart.toLocal8Bit(); // for holding the char *
0072     if (ctags::tagsFind(file, &entry, tagpartBArray.data(), TAG_OBSERVECASE | (partial ? TAG_PARTIALMATCH : TAG_FULLMATCH)) == ctags::TagSuccess) {
0073         do {
0074             n++;
0075         } while (ctags::tagsFindNext(file, &entry) == ctags::TagSuccess);
0076     }
0077 
0078     ctags::tagsClose(file);
0079 
0080     return n;
0081 }
0082 
0083 Tags::TagList Tags::getPartialMatchesNoi8n(const QString &tagFile, const QString &tagpart)
0084 {
0085     setTagsFile(tagFile);
0086     auto getExtension = [](const QString &fileUrl) -> QStringView {
0087         int dotPos = fileUrl.lastIndexOf(QLatin1Char('.'));
0088         if (dotPos > -1) {
0089             return QStringView(fileUrl).mid(dotPos + 1);
0090         }
0091         return QStringView();
0092     };
0093     Tags::TagList list;
0094 
0095     if (tagpart.isEmpty()) {
0096         return list;
0097     }
0098 
0099     ctags::tagFileInfo info;
0100     ctags::tagFile *file = ctags::tagsOpen(_tagsfile.toLocal8Bit().constData(), &info);
0101     ctags::tagEntry entry;
0102 
0103     QByteArray tagpartBArray = tagpart.toLocal8Bit(); // for holding the char *
0104     if (ctags::tagsFind(file, &entry, tagpartBArray.data(), TAG_OBSERVECASE | TAG_PARTIALMATCH) == ctags::TagSuccess) {
0105         do {
0106             QString file = QString::fromLocal8Bit(entry.file);
0107             QString type(CTagsKinds::findKindNoi18n(entry.kind, getExtension(file)));
0108 
0109             if (type.isEmpty() && file.endsWith(QLatin1String("Makefile"))) {
0110                 type = QStringLiteral("macro");
0111             }
0112 
0113             list << TagEntry(QString::fromLocal8Bit(entry.name), type, file, QString::fromLocal8Bit(entry.address.pattern));
0114         } while (ctags::tagsFindNext(file, &entry) == ctags::TagSuccess);
0115     }
0116 
0117     ctags::tagsClose(file);
0118 
0119     return list;
0120 }
0121 
0122 Tags::TagList Tags::getMatches(const QString &tagpart, bool partial, const QStringList &types)
0123 {
0124     Tags::TagList list;
0125 
0126     if (tagpart.isEmpty()) {
0127         return list;
0128     }
0129 
0130     ctags::tagFileInfo info;
0131     ctags::tagFile *file = ctags::tagsOpen(_tagsfile.toLocal8Bit().constData(), &info);
0132     ctags::tagEntry entry;
0133 
0134     QByteArray tagpartBArray = tagpart.toLocal8Bit(); // for holding the char *
0135     if (ctags::tagsFind(file, &entry, tagpartBArray.data(), TAG_OBSERVECASE | (partial ? TAG_PARTIALMATCH : TAG_FULLMATCH)) == ctags::TagSuccess) {
0136         do {
0137             QString file = QString::fromLocal8Bit(entry.file);
0138             QString type(CTagsKinds::findKind(entry.kind, file.section(QLatin1Char('.'), -1)));
0139 
0140             if (type.isEmpty() && file.endsWith(QLatin1String("Makefile"))) {
0141                 type = QStringLiteral("macro");
0142             }
0143             if (types.isEmpty() || types.contains(QString::fromLocal8Bit(entry.kind))) {
0144                 list << TagEntry(QString::fromLocal8Bit(entry.name), type, file, QString::fromLocal8Bit(entry.address.pattern));
0145             }
0146         } while (ctags::tagsFindNext(file, &entry) == ctags::TagSuccess);
0147     }
0148 
0149     ctags::tagsClose(file);
0150 
0151     return list;
0152 }
0153 
0154 void Tags::setTagsFile(const QString &file)
0155 {
0156     _tagsfile = file;
0157 }
0158 
0159 QString Tags::getTagsFile()
0160 {
0161     return _tagsfile;
0162 }
0163 
0164 unsigned int Tags::numberOfPartialMatches(const QString &tagpart)
0165 {
0166     return numberOfMatches(tagpart, true);
0167 }
0168 
0169 unsigned int Tags::numberOfExactMatches(const QString &tagpart)
0170 {
0171     return numberOfMatches(tagpart, false);
0172 }
0173 
0174 Tags::TagList Tags::getPartialMatches(const QString &tagpart)
0175 {
0176     return getMatches(tagpart, true);
0177 }
0178 
0179 Tags::TagList Tags::getExactMatches(const QString &tag)
0180 {
0181     return getMatches(tag, false);
0182 }
0183 
0184 Tags::TagList Tags::getPartialMatches(const QString &file, const QString &tagpart)
0185 {
0186     setTagsFile(file);
0187     return getMatches(tagpart, true);
0188 }
0189 
0190 Tags::TagList Tags::getExactMatches(const QString &file, const QString &tag)
0191 {
0192     setTagsFile(file);
0193     return getMatches(tag, false);
0194 }
0195 
0196 Tags::TagList Tags::getMatches(const QString &file, const QString &tagpart, bool partial, const QStringList &types)
0197 {
0198     setTagsFile(file);
0199     return getMatches(tagpart, partial, types);
0200 }
0201 
0202 // kate: space-indent off; indent-width 4; tab-width 4; show-tabs on;