示例#1
0
std::string libclang_vim::stringize_cursor_kind_type(CXCursorKind const& kind) {
    if (clang_isAttribute(kind))
        return "Attribute";
    if (clang_isDeclaration(kind))
        return "Declaration";
    if (clang_isExpression(kind))
        return "Expression";
    if (clang_isPreprocessing(kind))
        return "Preprocessing";
    if (clang_isReference(kind))
        return "Reference";
    if (clang_isStatement(kind))
        return "Statement";
    if (clang_isTranslationUnit(kind))
        return "TranslationUnit";
    if (clang_isUnexposed(kind))
        return "Unexposed";
    if (clang_isInvalid(kind))
        return "";
    return "Unknown";
}
void
Html_File::write_token(FILE* f,
                       CXFile file,
                       CXToken tok,
                       const char* str,
                       unsigned line,
                       unsigned column)
{
  static bool preprocessor = false;
  static bool include = false;

  CXSourceLocation tloc = clang_getTokenLocation(tu_file_->tu(), tok);
  CXCursor c = clang_getCursor(tu_file_->tu(), tloc);

  if (cur_line_ <= line) cur_column_ = 1;

  for (; cur_line_ <= line; ++cur_line_)
    fprintf (f, "\n<a name=\"l%05i\"></a>%05i", cur_line_, cur_line_);

  for (; cur_column_ <= column; ++cur_column_)
    fprintf (f , " ");

  switch (clang_getTokenKind(tok)) {
  case (CXToken_Punctuation):
    if (str[0] == '#')
      preprocessor = true;
    fprintf(f, "%s", str);
    break;
  case (CXToken_Keyword):
    fprintf(f, "<span class=\"keyword\">%s</span>", str);
    break;
  case (CXToken_Comment):
    fprintf(f, "<span class=\"comment\">%s</span>", str);
    break;
  case (CXToken_Literal): {
    //include = false; // disable include links for now
    if (include) {
      include = false;
      // found an include file
      std::string t;
      const char* p = str;
      while (*p) {
        if (*p != '"')
          t += *p;
        ++p;
      }

      // first, use this file's path, then all the include paths
      bool found_include = false;
      char path[PATH_MAX];
      std::string includefile = realpath(dirname(tu_file_->source_filename()), path);
      includefile += "/" + t;
      struct stat st;
      if (stat(includefile.c_str(), &st) == 0) {
        found_include = true;
      } else {
        for (std::vector<std::string>::const_iterator i = includes_.begin(),
               e = includes_.end(); i != e; ++i) {
          includefile = realpath((*i).c_str(), path);
          includefile += "/" + t;
          if (stat(includefile.c_str(), &st) == 0) {
            found_include = true;
            break;
          }
        }
      }
      if (found_include) {
        if (files_.find(includefile) != files_.end()) {
          t = make_filename(includefile, html_dir_, prefix_, ".html", false);
          fprintf(f, "<a class=\"code\" href=\"%s\" title="">%s</a>",
                  t.c_str(), str);
          break;
        }
        std::map<std::string, Definition>::iterator i = defmap_.find(includefile);
        if (i != defmap_.end()) {
          t = i->second.file.c_str();
          fprintf(f, "<a class=\"code\" href=\"%s\" title="">%s</a>",
                  t.c_str(), str);
          break;
        }
      }
    }
    // not an include or include not found
    std::string s = fix(str);
    fprintf(f, "%s",  s.c_str() );
    break;
  }
  case (CXToken_Identifier): {
    if (preprocessor) {
      preprocessor = false;
      if (strcmp(str, "include") == 0)
        include = true;
      fprintf(f, "<span class=\"code\">%s</span>", str);
      break;
    }

    if (clang_isUnexposed(c.kind)) {
      fprintf(f, "<span class=\"code\">%s</span>", str);
      fprintf(f, "<!-- origin line: %i : %s : kind = %i -->",
              __LINE__, str, c.kind);
      break;
    }

    // Calling clang_getCursorDefinition() does not work properly
    // for template classes, i.e., it will find the method
    // declaration, not the definition, if they differ.  However,
    // once you have the declaration's location, you can use it
    // get that cursor, and find the definition that way.
    CXSourceLocation decloc =
      clang_getCursorLocation(clang_getCursorDefinition(c));
    CXCursor cref =
      clang_getCursorDefinition(clang_getCursor(tu_file_->tu(),
                                                decloc));

    if (clang_isUnexposed(cref.kind)) {
      fprintf(f, "<span class=\"code\">%s</span>", str);
          fprintf(f, "<!-- origin line: %i : (ref) %s : kind = %i -->",
                  __LINE__, str, cref.kind);
      break;
    }

    std::string rfile;
    std::string html_dir;
    unsigned refl = line;
    bool found = false;

    if (!clang_Cursor_isNull(cref) && cref.kind != CXCursor_Namespace) {
      CXSourceLocation refloc = clang_getCursorLocation(cref);
      if (!clang_equalLocations(tloc, refloc)) {
        CXFile cxfile;
        unsigned col;
        unsigned off;
        clang_getExpansionLocation(refloc, &cxfile, &refl, &col, &off);
        if (cxfile == file) {
          found = true;
          fprintf(f, "<!-- origin line: %i : (ref) %s : kind = %i -->",
                  __LINE__, str, cref.kind);
        }
        else {
          CXString cxfn = clang_getFileName(cxfile);
          const char* fn = clang_getCString(cxfn);
          if (fn) {
            if (files_.find(fn) != files_.end()) {
              rfile = fn;
              found = true;
              fprintf(f, "<!-- origin line: %i : (ref) %s : kind = %i -->",
                      __LINE__, str, cref.kind);
            }
          }
          clang_disposeString(cxfn);
        }
      }
    }
    else if (!clang_isDeclaration(c.kind) && c.kind != CXCursor_Namespace) {
      CXCursor ref = clang_getCursorReferenced(c);
      if (ref.kind != CXCursor_Namespace) {
        std::string fsn = munge_fullyscopedname(fullyScopedName(ref));
        if (fsn.empty()) {
            fprintf(f, "<!-- origin line: %i : (fsn empty) %s : kind = %i -->",
                    __LINE__, str, c.kind);
        } else {
          std::map<std::string, Definition>::iterator r = defmap_.find(fsn);
          if (r != defmap_.end()) {
            found = true;
            fprintf(f, "<!-- origin line: %i : %s : kind = %i -->",
                    __LINE__, fsn.c_str(), c.kind);
            rfile = r->second.file.c_str();
            html_dir = r->second.html_path.c_str();
            refl = r->second.line;
          }
        }
      }
    }

    // since we are linking to lines, no need to link to same line
    if (found && (!rfile.empty() || refl != line)) {
      if (!rfile.empty())
        rfile = make_filename(rfile, html_dir, prefix_, ".html", !html_dir.empty());
      fprintf(f, "<a class=\"code\" href=\"%s#l%05i\" title="">%s</a>",
              rfile.c_str(), refl , str);
      break;
    }
    fprintf(f, "<span class=\"code\">%s</span>", str);
    break;
  }
  }
  cur_column_ += strlen(str);
}
示例#3
0
bool cursor::isUnexposed() const
{
    return clang_isUnexposed(kind());
}