static void codifyLines(CodeOutputInterface &ol,FileDef *fd,const char *text, uint &line,uint &column,const char *fontClass=0) { if (fontClass) ol.startFontClass(fontClass); const char *p=text,*sp=p; char c; bool done=FALSE; while (!done) { sp=p; while ((c=*p++) && c!='\n') { column++; } if (c=='\n') { line++; int l = (int)(p-sp-1); column=l+1; char *tmp = (char*)malloc(l+1); memcpy(tmp,sp,l); tmp[l]='\0'; ol.codify(tmp); free(tmp); if (fontClass) ol.endFontClass(); ol.endCodeLine(); ol.startCodeLine(TRUE); writeLineNumber(ol,fd,line); if (fontClass) ol.startFontClass(fontClass); } else { ol.codify(sp); done=TRUE; } } if (fontClass) ol.endFontClass(); }
void ClangParser::linkInclude(CodeOutputInterface &ol,FileDef *fd, uint &line,uint &column,const char *text) { QCString incName = text; incName = incName.mid(1,incName.length()-2); // strip ".." or <..> FileDef *ifd=0; if (!incName.isEmpty()) { FileName *fn = Doxygen::inputNameDict->find(incName); if (fn) { bool found=false; FileNameIterator fni(*fn); // for each include name for (fni.toFirst();!found && (ifd=fni.current());++fni) { // see if this source file actually includes the file found = fd->isIncluded(ifd->absFilePath()); //printf(" include file %s found=%d\n",ifd->absFilePath().data(),found); } } } if (ifd) { ol.writeCodeLink(ifd->getReference(),ifd->getOutputFileBase(),0,text,ifd->briefDescriptionAsTooltip()); } else { codifyLines(ol,ifd,text,line,column,"preprocessor"); } }
void ClangParser::linkInclude(CodeOutputInterface &ol, QSharedPointer<FileDef> fd, uint &line, uint &column, const QString &text) { QString incName = text; incName = incName.mid(1, incName.length() - 2); // strip ".." or <..> QSharedPointer<FileDef> ifd; if (! incName.isEmpty()) { QSharedPointer<FileNameList> fn = Doxy_Globals::inputNameDict->find(incName); if (fn) { bool found = false; // for each include name, see if this source file actually includes the file for (auto fd : *fn) { if (found) { break; } ifd = fd; found = fd->isIncluded(ifd->getFilePath()); } } } if (ifd) { ol.writeCodeLink(ifd->getReference(), ifd->getOutputFileBase(), 0, text, ifd->briefDescriptionAsTooltip()); } else { codifyLines(ol, ifd, text, line, column, "preprocessor"); } }
static void writeLineNumber(CodeOutputInterface &ol,FileDef *fd,uint line) { Definition *d = fd ? fd->getSourceDefinition(line) : 0; if (d && d->isLinkable()) { g_currentDefinition=d; g_currentLine=line; MemberDef *md = fd->getSourceMember(line); if (md && md->isLinkable()) // link to member { if (g_currentMemberDef!=md) // new member, start search for body { g_searchForBody=TRUE; g_insideBody=FALSE; g_bracketCount=0; } g_currentMemberDef=md; ol.writeLineNumber(md->getReference(), md->getOutputFileBase(), md->anchor(), line); } else // link to compound { g_currentMemberDef=0; ol.writeLineNumber(d->getReference(), d->getOutputFileBase(), d->anchor(), line); } } else // no link { ol.writeLineNumber(0,0,0,line); } // set search page target if (Doxygen::searchIndex) { QCString lineAnchor; lineAnchor.sprintf("l%05d",line); ol.setCurrentDoc(fd,lineAnchor,TRUE); } //printf("writeLineNumber(%d) g_searchForBody=%d\n",line,g_searchForBody); }
static void codifyLines(CodeOutputInterface &ol, QSharedPointer<FileDef> fd, const QString &text, uint &line, uint &column, const QString &fontClass) { if (! fontClass.isEmpty()) { ol.startFontClass(fontClass); } const QChar *p = text.constData(); const QChar *sp = p; const QChar *ptr = p; QChar c; bool done = false; while (! done) { sp = p; while ((c = *p++) != 0 && c != '\n') { column++; } if (c == '\n') { line++; int l = (int)(p - sp - 1); column = l + 1; char *tmp = (char *)malloc(l + 1); memcpy(tmp, sp, l); tmp[l] = '\0'; ol.codify(tmp); free(tmp); if (! fontClass.isEmpty()) { ol.endFontClass(); } ol.endCodeLine(); ol.startCodeLine(true); writeLineNumber(ol, fd, line); if (! fontClass.isEmpty()) { ol.startFontClass(fontClass.toUtf8()); } } else { ol.codify(text.mid(sp - ptr) ); done = true; } } if (! fontClass.isEmpty()) { ol.endFontClass(); } }
static void writeLineNumber(CodeOutputInterface &ol, QSharedPointer<FileDef> fd, uint line) { QSharedPointer<Definition> d; if (fd) { d = fd->getSourceDefinition(line); } if (d && d->isLinkable()) { g_currentDefinition = d; g_currentLine = line; QSharedPointer<MemberDef> md = fd->getSourceMember(line); if (md && md->isLinkable()) { // link to member if (g_currentMemberDef != md) { // new member, start search for body g_searchForBody = true; g_insideBody = false; g_bracketCount = 0; } g_currentMemberDef = md; ol.writeLineNumber(md->getReference(), md->getOutputFileBase(), md->anchor(), line); } else { // link to compound g_currentMemberDef = QSharedPointer<MemberDef>(); ol.writeLineNumber(d->getReference(), d->getOutputFileBase(), d->anchor(), line); } } else { // no link ol.writeLineNumber(0, 0, 0, line); } // set search page target if (Doxy_Globals::searchIndex) { QString lineAnchor = QString("l%1").arg(line, 5, 10, QChar('0')); ol.setCurrentDoc(fd, lineAnchor, true); } }
static void writeMultiLineCodeLink(CodeOutputInterface &ol, QSharedPointer<FileDef> fd, uint &line, uint &column, QSharedPointer<Definition> d, const QString &text) { static bool sourceTooltips = Config::getBool("source-tooltips"); TooltipManager::instance()->addTooltip(d); QString ref = d->getReference(); QString file = d->getOutputFileBase(); QString anchor = d->anchor(); QString tooltip; if (! sourceTooltips) { // fall back to simple "title" tooltips tooltip = d->briefDescriptionAsTooltip(); } QString tmp; for (auto c : text) { if (c == '\n') { line++; ol.writeCodeLink(ref, file, anchor, tmp, tooltip); ol.endCodeLine(); ol.startCodeLine(true); writeLineNumber(ol, fd, line); tmp = ""; } else { column++; tmp += c; } } if (! tmp.isEmpty() ) { ol.writeCodeLink(ref, file, anchor, tmp, tooltip); } }
static void writeMultiLineCodeLink(CodeOutputInterface &ol, FileDef *fd,uint &line,uint &column, Definition *d, const char *text) { static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS); TooltipManager::instance()->addTooltip(d); QCString ref = d->getReference(); QCString file = d->getOutputFileBase(); QCString anchor = d->anchor(); QCString tooltip; if (!sourceTooltips) // fall back to simple "title" tooltips { tooltip = d->briefDescriptionAsTooltip(); } bool done=FALSE; char *p=(char *)text; while (!done) { char *sp=p; char c; while ((c=*p++) && c!='\n') { column++; } if (c=='\n') { line++; *(p-1)='\0'; //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp); ol.writeCodeLink(ref,file,anchor,sp,tooltip); ol.endCodeLine(); ol.startCodeLine(TRUE); writeLineNumber(ol,fd,line); } else { //printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp); ol.writeCodeLink(ref,file,anchor,sp,tooltip); done=TRUE; } } }
void TooltipManager::writeTooltips(CodeOutputInterface &ol) { QDictIterator<Definition> di(p->tooltipInfo); Definition *d; for (di.toFirst();(d=di.current());++di) { DocLinkInfo docInfo; docInfo.name = d->qualifiedName(); docInfo.ref = d->getReference(); docInfo.url = d->getOutputFileBase(); docInfo.anchor = d->anchor(); SourceLinkInfo defInfo; if (d->getBodyDef() && d->getStartBodyLine()!=-1) { defInfo.file = d->getBodyDef()->name(); defInfo.line = d->getStartBodyLine(); defInfo.url = d->getSourceFileBase(); defInfo.anchor = d->getSourceAnchor(); } SourceLinkInfo declInfo; // TODO: fill in... QCString decl; if (d->definitionType()==Definition::TypeMember) { MemberDef *md = (MemberDef*)d; decl = md->declaration(); if (!decl.isEmpty() && decl.at(0)=='@') // hide enum values { decl.resize(0); } } ol.writeTooltip(di.currentKey(), // id docInfo, // symName decl, // decl d->briefDescriptionAsTooltip(), // desc defInfo, declInfo ); } }
void ClangParser::writeSources(CodeOutputInterface &ol,FileDef *fd) { TooltipManager::instance()->clearTooltips(); // (re)set global parser state g_currentDefinition=0; g_currentMemberDef=0; g_currentLine=0; g_searchForBody=FALSE; g_insideBody=FALSE; g_bracketCount=0; unsigned int line=1,column=1; QCString lineNumber,lineAnchor; ol.startCodeLine(TRUE); writeLineNumber(ol,fd,line); for (unsigned int i=0;i<p->numTokens;i++) { CXSourceLocation start = clang_getTokenLocation(p->tu, p->tokens[i]); unsigned int l, c; clang_getSpellingLocation(start, 0, &l, &c, 0); if (l > line) column = 1; while (line<l) { line++; ol.endCodeLine(); ol.startCodeLine(TRUE); writeLineNumber(ol,fd,line); } while (column<c) { ol.codify(" "); column++; } CXString tokenString = clang_getTokenSpelling(p->tu, p->tokens[i]); char const *s = clang_getCString(tokenString); CXCursorKind cursorKind = clang_getCursorKind(p->cursors[i]); CXTokenKind tokenKind = clang_getTokenKind(p->tokens[i]); //printf("%d:%d %s cursorKind=%d tokenKind=%d\n",line,column,s,cursorKind,tokenKind); switch (tokenKind) { case CXToken_Keyword: if (strcmp(s,"operator")==0) { linkIdentifier(ol,fd,line,column,s,i); } else { codifyLines(ol,fd,s,line,column, cursorKind==CXCursor_PreprocessingDirective ? "preprocessor" : keywordToType(s)); } break; case CXToken_Literal: if (cursorKind==CXCursor_InclusionDirective) { linkInclude(ol,fd,line,column,s); } else if (s[0]=='"' || s[0]=='\'') { codifyLines(ol,fd,s,line,column,"stringliteral"); } else { codifyLines(ol,fd,s,line,column); } break; case CXToken_Comment: codifyLines(ol,fd,s,line,column,"comment"); break; default: // CXToken_Punctuation or CXToken_Identifier if (tokenKind==CXToken_Punctuation) { detectFunctionBody(s); //printf("punct %s: %d\n",s,cursorKind); } switch (cursorKind) { case CXCursor_PreprocessingDirective: codifyLines(ol,fd,s,line,column,"preprocessor"); break; case CXCursor_MacroDefinition: codifyLines(ol,fd,s,line,column,"preprocessor"); break; case CXCursor_InclusionDirective: linkInclude(ol,fd,line,column,s); break; case CXCursor_MacroExpansion: linkMacro(ol,fd,line,column,s); break; default: if (tokenKind==CXToken_Identifier || (tokenKind==CXToken_Punctuation && // for operators (cursorKind==CXCursor_DeclRefExpr || cursorKind==CXCursor_MemberRefExpr || cursorKind==CXCursor_CallExpr || cursorKind==CXCursor_ObjCMessageExpr) ) ) { linkIdentifier(ol,fd,line,column,s,i); if (Doxygen::searchIndex) { ol.addWord(s,FALSE); } } else { codifyLines(ol,fd,s,line,column); } break; } } clang_disposeString(tokenString); } ol.endCodeLine(); TooltipManager::instance()->writeTooltips(ol); }
void ClangParser::writeSources(CodeOutputInterface &ol, QSharedPointer<FileDef> fd) { TooltipManager::instance()->clearTooltips(); // set global parser state g_currentDefinition = QSharedPointer<Definition>(); g_currentMemberDef = QSharedPointer<MemberDef>(); g_currentLine = 0; g_searchForBody = false; g_insideBody = false; g_bracketCount = 0; unsigned int line = 1; unsigned int column = 1; QString lineNumber; QString lineAnchor; ol.startCodeLine(true); writeLineNumber(ol, fd, line); for (unsigned int i = 0; i < p->numTokens; i++) { CXSourceLocation start = clang_getTokenLocation(p->tu, p->tokens[i]); unsigned int t_line; unsigned int t_col; clang_getSpellingLocation(start, 0, &t_line, &t_col, 0); if (t_line > line) { column = 1; } while (line < t_line) { line++; ol.endCodeLine(); ol.startCodeLine(true); writeLineNumber(ol, fd, line); } while (column < t_col) { ol.codify(" "); column++; } CXString tokenString = clang_getTokenSpelling(p->tu, p->tokens[i]); char const *s = clang_getCString(tokenString); CXCursorKind cursorKind = clang_getCursorKind(p->cursors[i]); CXTokenKind tokenKind = clang_getTokenKind(p->tokens[i]); switch (tokenKind) { case CXToken_Keyword: if (strcmp(s, "operator") == 0) { linkIdentifier(ol, fd, line, column, s, i); } else { QString temp; if (cursorKind == CXCursor_PreprocessingDirective) { temp = "preprocessor"; } else { temp = keywordToType(s); } codifyLines(ol, fd, s, line, column, temp); } break; case CXToken_Literal: if (cursorKind == CXCursor_InclusionDirective) { linkInclude(ol, fd, line, column, s); } else if (s[0] == '"' || s[0] == '\'') { codifyLines(ol, fd, s, line, column, "stringliteral"); } else { codifyLines(ol, fd, s, line, column, ""); } break; case CXToken_Comment: codifyLines(ol, fd, s, line, column, "comment"); break; default: // CXToken_Punctuation or CXToken_Identifier if (tokenKind == CXToken_Punctuation) { detectFunctionBody(s); } switch (cursorKind) { case CXCursor_PreprocessingDirective: codifyLines(ol, fd, s, line, column, "preprocessor"); break; case CXCursor_MacroDefinition: codifyLines(ol, fd, s, line, column, "preprocessor"); break; case CXCursor_InclusionDirective: linkInclude(ol, fd, line, column, s); break; case CXCursor_MacroExpansion: linkMacro(ol, fd, line, column, s); break; default: if (tokenKind == CXToken_Identifier || (tokenKind == CXToken_Punctuation && (cursorKind == CXCursor_DeclRefExpr || cursorKind == CXCursor_MemberRefExpr || cursorKind == CXCursor_CallExpr || cursorKind == CXCursor_ObjCMessageExpr)) ) { linkIdentifier(ol, fd, line, column, s, i); if (Doxy_Globals::searchIndex) { ol.addWord(s, false); } } else { codifyLines(ol, fd, s, line, column, ""); } break; } } clang_disposeString(tokenString); } ol.endCodeLine(); TooltipManager::instance()->writeTooltips(ol); }