예제 #1
0
void GRTags::findSymbols(const ByteArray &pattern)
{
    std::string value;
    if (mDB->Get(leveldb::ReadOptions(), leveldb::Slice(pattern.constData(), pattern.size()), &value).ok()) {
        Deserializer deserializer(value.c_str(), value.size());
        Map<Location, bool> symbols;
        deserializer >> symbols;
        for (Map<Location, bool>::const_iterator it = symbols.begin(); it != symbols.end(); ++it) {
            bool ok;
            switch (mMode) {
            case FindSymbols:
                ok = !it->second;
                break;
            case FindReferences:
                ok = it->second;
                break;
            case FindAll:
                ok = true;
                break;
            default:
                assert(0);
                return;
            }
            if (ok) {
                error() << it->first.key(mKeyFlags);
            }
        }
    }
void GccArguments::addFlags(const List<ByteArray> &extraFlags)
{
    const int count = extraFlags.size();
    for (int i=0; i<count; ++i) {
        ByteArray flag = extraFlags.at(i);
        if (flag.startsWith("-I")) {
            Path p = Path::resolved(flag.constData() + 2);
            flag.replace(2, flag.size() - 2, p);
        }
        mClangArgs.append(flag);
    }
}
static inline GccArguments::Lang guessLang(const Path &fullPath)
{
    ByteArray compiler = fullPath.fileName();
    ByteArray c;
    int dash = compiler.lastIndexOf('-');
    if (dash >= 0) {
        c = ByteArray(compiler.constData() + dash + 1, compiler.size() - dash - 1);
    } else {
        c = ByteArray(compiler.constData(), compiler.size());
    }

    if (c.size() != compiler.size()) {
        bool isVersion = true;
        for (int i=0; i<c.size(); ++i) {
            if ((c.at(i) < '0' || c.at(i) > '9') && c.at(i) != '.') {
                isVersion = false;
                break;
            }
        }
        if (isVersion) {
            dash = compiler.lastIndexOf('-', dash - 1);
            if (dash >= 0) {
                c = compiler.mid(dash + 1, compiler.size() - c.size() - 2 - dash);
            } else {
                c = compiler.left(dash);
            }
        }
    }

    GccArguments::Lang lang = GccArguments::NoLang;
    if (c.startsWith("g++") || c.startsWith("c++")) {
        lang = GccArguments::CPlusPlus;
    } else if (c.startsWith("gcc") || c.startsWith("cc")) {
        lang = GccArguments::C;
    }
    return lang;
}
void CompletionJob::processDiagnostics(CXCodeCompleteResults* results)
{
    if (!testLog(CompilationError))
        return;

    const unsigned int numDiags = clang_codeCompleteGetNumDiagnostics(results);
    for (unsigned int curDiag = 0; curDiag < numDiags; ++curDiag) {
        CXDiagnostic diagnostic = clang_codeCompleteGetDiagnostic(results, curDiag);
        const unsigned diagnosticOptions = (CXDiagnostic_DisplaySourceLocation|
                                            CXDiagnostic_DisplayColumn|
                                            CXDiagnostic_DisplaySourceRanges|
                                            CXDiagnostic_DisplayOption|
                                            CXDiagnostic_DisplayCategoryId|
                                            CXDiagnostic_DisplayCategoryName);
        const ByteArray text = RTags::eatString(clang_formatDiagnostic(diagnostic, diagnosticOptions));
        log(CompilationError, "%s", text.constData());

        clang_disposeDiagnostic(diagnostic);
    }
    log(CompilationError, "$");
}
bool Connection::send(int id, const ByteArray &message)
{
    if (!mClient->isConnected()) {
        ::error("Trying to send message to unconnected client (%d)", id);
        return false;
    }

    if (mSilent)
        return true;

    ByteArray header, data;
    {
        if (message.size()) {
            Serializer strm(data);
            strm << id;
            strm.write(message.constData(), message.size());
        }
        Serializer strm(header);
        strm << data.size();
    }
    mPendingWrite += (header.size() + data.size());
    return mClient->write(header) && mClient->write(data);
}
예제 #6
0
bool GRTags::exec(int argc, char **argv)
{
    option options[] = {
        { "help", no_argument, 0, 'h' },
        { "version", no_argument, 0, 'V' },
        { "verbose", no_argument, 0, 'v' },
        { "exclude", required_argument, 0, 'e' },
        { "references", required_argument, 0, 'R' },
        { "list-symbols", optional_argument, 0, 'S' },
        { "find-symbols", required_argument, 0, 'F' },
        { "all-symbols", required_argument, 0, 'l' },
        { "show-context", no_argument, 0, 'C' },
        { "find-file", optional_argument, 0, 'P' },
        { "dir", required_argument, 0, 'd' },
        { "dump", no_argument, 0, 's' },
        { "create", no_argument, 0, 'c' },
        { "silent", no_argument, 0, 'i' },
        { "update", no_argument, 0, 'u' },
        { "match-icase", no_argument, 0, 'I' },
        { "find-file-prefer-exact", no_argument, 0, 'A' },
        { "absolute-path", no_argument, 0, 'K' },
        { 0, 0, 0, 0 }
    };

    int logLevel = 0;
    Path dir;
    int c;
    const ByteArray shortOptions = RTags::shortOptions(options);
    ByteArray pattern;
    while ((c = getopt_long(argc, argv, shortOptions.constData(), options, 0)) != -1) {
        switch (c) {
        case '?':
            return false;
        case 'h':
            printf("grtags [...options]\n"
                   "  --help|-h                    Display this help\n"
                   "  --version|-V                 Display version information\n"
                   "  --verbose|-v                 Increase verbosity\n"
                   "  --silent|-i                  Be silent\n"
                   "  --exclude|-e [filter]        Exclude this pattern (e.g. .git, *.cpp)\n"
                   "  --references|-R [arg]        Show references to arg\n"
                   "  --list-symbols|-S [arg]      List symbols matching arg\n"
                   "  --all-symbols|-l [arg]       List symbols and references matching arg\n"
                   "  --find-symbols|-F [arg]      Find symbols matching arg\n"
                   "  --context|-C                 Show context\n"
                   "  --dump|-s                    Dump db contents\n"
                   "  --create|-c                  Force creation of new DB\n"
                   "  --update|-u                  Update existing DB (noop with no DB)\n"
                   "  --find-file|-P [arg]         List files matching optional arg\n"
                   "  --match-icase|-I             Match paths case insensitively\n"
                   "  --find-file-prefer-exact|-A  Use to make --find-file prefer exact matches over partial\n"
                   "  --absolute-path|-K           Print files with absolute path.\n"
                   "  --dir|-d [arg]               Parse this directory (default .)\n");

            return true;
        case 'V':
            printf("GRTags version 0.2\n");
            return true;
        case 'C':
            mKeyFlags |= Location::ShowContext;
            break;
        case 'A':
            mFlags |= PreferExact;
            break;
        case 'I':
            mFlags |= MatchCaseInsensitive;
            break;
        case 'K':
            mFlags |= AbsolutePath;
            break;
        case 'P':
            mMode = Paths;
            if (optarg) {
                pattern = optarg;
            } else if (optind < argc && *argv[optind] != '-') {
                pattern = argv[optind++];
            }
            break;
        case 'R':
            mMode = FindReferences;
            pattern = optarg;
            break;
        case 'F':
            mMode = FindSymbols;
            pattern = optarg;
            break;
        case 'l':
            mMode = FindAll;
            pattern = optarg;
            break;
        case 'S':
            mMode = ListSymbols;
            if (optarg) {
                pattern = optarg;
            } else if (optind < argc && *argv[optind] != '-') {
                pattern = argv[optind++];
            }
            break;
        case 'c':
            mMode = Create;
            break;
        case 'u':
            mMode = Update;
            break;
        case 'e':
            mFilters.append(optarg);
            break;
        case 'v':
            if (logLevel >= 0)
                ++logLevel;
            break;
        case 'i':
            logLevel = -1;
            break;
        case 's':
            mMode = Dump;
            break;
        case 'd':
            dir = optarg;
            if (!dir.isDir()) {
                fprintf(stderr, "%s is not a valid directory\n", optarg);
                return false;
            }
            break;
        }
    }
    if (dir.isEmpty()) {
        Path p = Path::pwd();
        while (!p.isEmpty()) {
            const Path db = p + "/.gr";
            if (db.isDir()) {
                dir = p;
                break;
            }
            p = p.parentDir();
        }
        if (dir.isEmpty()) {
            if (mMode == Detect)
                mMode = Create;
            if (mMode == Create)
                dir = Path::pwd();
        }
    }
    if (dir.isEmpty()) {
        warning() << "Can't find database";
        return false;
    }

    initLogging(logLevel, Path(), 0);
    if (!load(dir + "/.gr"))
        return false;
    switch (mMode) {
    case Dump:
        dump();
        return true;
    case Update:
    case Create:
        dir.visit(&GRTags::visit, this);
        if (parseFiles())
            return save();
        return true;
    case Paths:
        paths(pattern);
        break;
    case FindReferences:
    case FindAll:
    case FindSymbols:
        findSymbols(pattern);
        break;
    case ListSymbols:
        listSymbols(pattern);
        break;
    case Detect:
        break;
    }
    return false;
}