From 62d24d83a13d3a8bf08b83e485358e4a7e5e226b Mon Sep 17 00:00:00 2001 From: Weston Thayer Date: Tue, 6 Jan 2015 17:18:24 -0500 Subject: Add support for basic XML syntax highlighting. --- doc/dbusxml.doc | 5 + src/Makefile.in | 2 +- src/dbusxmlscanner.cpp | 43 +- src/libdoxygen.pro.in | 2 + src/libdoxygen.t.in | 3 + src/util.cpp | 2 +- src/xmlcode.h | 37 + src/xmlcode.l | 411 ++++ winbuild/Doxygen.vcproj | 5934 ++++++++++++++++++++++++----------------------- 9 files changed, 3459 insertions(+), 2980 deletions(-) create mode 100644 src/xmlcode.h create mode 100644 src/xmlcode.l diff --git a/doc/dbusxml.doc b/doc/dbusxml.doc index e487126..9ecf592 100644 --- a/doc/dbusxml.doc +++ b/doc/dbusxml.doc @@ -9,6 +9,11 @@ all XML comments starting with '*' or '!'. An additional '<' can be used to assign the documentation string to the previous entity instead of the one following the comment. +Doxygen will also show syntax highlighting for XML examples. Note that +in order for XML comments to show up, you must use 2 exclamation marks +instead of one. The extra ! will be stripped out for you. This is due +to a conflict with Doxygen's hidden comments. + Note that before the parsing of DBus XML file works one has to assign the .xml extension to the DBus XML parser using the following configuration option: diff --git a/src/Makefile.in b/src/Makefile.in index ffe7c16..865740d 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -48,6 +48,6 @@ distclean: clean ce_parse.cpp ce_parse.h tag.cpp commentscan.cpp \ declinfo.cpp defargs.cpp commentcnv.cpp doctokenizer.cpp \ pycode.cpp pyscanner.cpp fortrancode.cpp fortranscanner.cpp \ - vhdlscanner.cpp vhdlcode.cpp tclscanner.cpp + xmlcode.cpp vhdlscanner.cpp vhdlcode.cpp tclscanner.cpp FORCE: diff --git a/src/dbusxmlscanner.cpp b/src/dbusxmlscanner.cpp index aa3cc47..90d51cd 100644 --- a/src/dbusxmlscanner.cpp +++ b/src/dbusxmlscanner.cpp @@ -28,6 +28,11 @@ #include "util.h" #include "arguments.h" +#include "outputgen.h" +#include "memberdef.h" + +#include "xmlcode.h" + // ----------------------------------------------------------------------- // Convenience defines: // ----------------------------------------------------------------------- @@ -858,24 +863,30 @@ void DBusXMLScanner::parseInput(const char * fileName, bool DBusXMLScanner::needsPreprocessing(const QCString & /* extension */) { return (false); } -void DBusXMLScanner::parseCode(CodeOutputInterface & /* codeOutIntf */, - const char * /* scopeName */, - const QCString & /* input */, - SrcLangExt /* lang */, - bool /* isExampleBlock */, - const char * /* exampleName */, - FileDef * /* fileDef */, - int /* startLine */, - int /* endLine */, - bool /* inlineFragment */, - MemberDef * /* memberDef */, - bool /*showLineNumbers*/, - Definition * /* searchCtx */, - bool /*collectXRefs*/ ) -{ } +void DBusXMLScanner::parseCode(CodeOutputInterface & codeOutIntf, + const char * scopeName, + const QCString & input, + SrcLangExt /*lang*/, + bool isExampleBlock, + const char * exampleName, + FileDef * fileDef, + int startLine, + int endLine, + bool inlineFragment, + MemberDef * memberDef, + bool showLineNumbers, + Definition * searchCtx, + bool collectXRefs ) +{ + parseXmlCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName, + fileDef,startLine,endLine,inlineFragment,memberDef, + showLineNumbers,searchCtx,collectXRefs); +} void DBusXMLScanner::resetCodeParserState() -{ } +{ + resetXmlCodeParserState(); +} void DBusXMLScanner::parsePrototype(const char * /* text */) { } diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in index 39df3cd..47e5673 100644 --- a/src/libdoxygen.pro.in +++ b/src/libdoxygen.pro.in @@ -122,6 +122,7 @@ HEADERS = arguments.h \ xmlgen.h \ docbookvisitor.h \ docbookgen.h \ + xmlcode.h \ vhdljjparser.h @@ -217,6 +218,7 @@ SOURCES = arguments.cpp \ ../generated_src/doxygen/doctokenizer.cpp \ ../generated_src/doxygen/pre.cpp \ ../generated_src/doxygen/pycode.cpp \ + ../generated_src/doxygen/xmlcode.cpp \ ../generated_src/doxygen/pyscanner.cpp \ ../generated_src/doxygen/scanner.cpp \ ../generated_src/doxygen/tclscanner.cpp \ diff --git a/src/libdoxygen.t.in b/src/libdoxygen.t.in index 1d242d0..37bd4c1 100644 --- a/src/libdoxygen.t.in +++ b/src/libdoxygen.t.in @@ -71,6 +71,9 @@ sub GenerateLex { #$ GenerateDep("\$(GENERATED_SRC)/pycode.cpp","pycode.l"); #$ GenerateLex("pycode",0); +#$ GenerateDep("\$(GENERATED_SRC)/xmlcode.cpp","xmlcode.l"); +#$ GenerateLex("xmlcode",0); + #$ GenerateDep("\$(GENERATED_SRC)/fortranscanner.cpp","fortranscanner.l"); #$ GenerateLex("fortranscanner",1); diff --git a/src/util.cpp b/src/util.cpp index 000de53..938c8d6 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -6837,7 +6837,7 @@ void initDefaultExtensionMapping() updateLanguageMapping(".md", "md"); updateLanguageMapping(".markdown", "md"); - //updateLanguageMapping(".xml", "dbusxml"); + updateLanguageMapping(".xml", "dbusxml"); } SrcLangExt getLanguageFromFileName(const QCString fileName) diff --git a/src/xmlcode.h b/src/xmlcode.h new file mode 100644 index 0000000..5a9c78c --- /dev/null +++ b/src/xmlcode.h @@ -0,0 +1,37 @@ +/****************************************************************************** + * + * + * + * Copyright (C) 1997-2014 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + + +#ifndef XMLCODE_H +#define XMLCODE_H + +#include "types.h" + +class CodeOutputInterface; +class FileDef; +class MemberDef; +class QCString; +class Definition; + +extern void parseXmlCode(CodeOutputInterface &,const char *,const QCString &, + bool ,const char *,FileDef *fd, + int startLine,int endLine,bool inlineFragment, + MemberDef *memberDef,bool showLineNumbers,Definition *searchCtx, + bool collectXRefs); +extern void resetXmlCodeParserState(); + +#endif diff --git a/src/xmlcode.l b/src/xmlcode.l new file mode 100644 index 0000000..ebba910 --- /dev/null +++ b/src/xmlcode.l @@ -0,0 +1,411 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2014 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ +/****************************************************************************** + * Parser for syntax hightlighting and references for XML + * written by Weston Thayer + ******************************************************************************/ + +%{ + +#include + +#include "xmlcode.h" + +#include "entry.h" +#include "doxygen.h" +#include "outputlist.h" +#include "util.h" +#include "membername.h" +#include "searchindex.h" +#include "config.h" +#include "filedef.h" +#include "tooltip.h" + +#define YY_NEVER_INTERACTIVE 1 +#define YY_NO_INPUT 1 + +static CodeOutputInterface * g_code; +static QCString g_curClassName; +static QCString g_parmType; +static QCString g_parmName; +static const char * g_inputString; //!< the code fragment as text +static int g_inputPosition; //!< read offset during parsing +static int g_inputLines; //!< number of line in the code fragment +static int g_yyLineNr; //!< current line number +static bool g_needsTermination; +static Definition *g_searchCtx; + +static QCString g_exampleName; +static QCString g_exampleFile; + +static QCString g_type; +static QCString g_name; +static QCString g_args; +static QCString g_classScope; + +static QCString g_CurrScope; + +static FileDef * g_sourceFileDef; +static Definition * g_currentDefinition; +static MemberDef * g_currentMemberDef; +static bool g_includeCodeFragment; +static const char * g_currentFontClass; + +static void codify(const char* text) +{ + g_code->codify(text); +} + +static void setCurrentDoc(const QCString &anchor) +{ + if (Doxygen::searchIndex) + { + if (g_searchCtx) + { + Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE); + } + else + { + Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE); + } + } +} + +/*! start a new line of code, inserting a line number if g_sourceFileDef + * is TRUE. If a definition starts at the current line, then the line + * number is linked to the documentation of that definition. + */ +static void startCodeLine() +{ + if (g_sourceFileDef) + { + Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr); + + if (!g_includeCodeFragment && d && d->isLinkableInProject()) + { + g_currentDefinition = d; + g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr); + //g_insideBody = FALSE; + g_classScope = d->name().copy(); + QCString lineAnchor; + lineAnchor.sprintf("l%05d",g_yyLineNr); + if (g_currentMemberDef) + { + g_code->writeLineNumber(g_currentMemberDef->getReference(), + g_currentMemberDef->getOutputFileBase(), + g_currentMemberDef->anchor(),g_yyLineNr); + setCurrentDoc(lineAnchor); + } + else + { + g_code->writeLineNumber(d->getReference(), + d->getOutputFileBase(), + 0,g_yyLineNr); + setCurrentDoc(lineAnchor); + } + } + else + { + g_code->writeLineNumber(0,0,0,g_yyLineNr); + } + } + + g_code->startCodeLine(g_sourceFileDef); + + if (g_currentFontClass) + { + g_code->startFontClass(g_currentFontClass); + } +} + +static void endFontClass() +{ + if (g_currentFontClass) + { + g_code->endFontClass(); + g_currentFontClass=0; + } +} + +static void endCodeLine() +{ + endFontClass(); + g_code->endCodeLine(); +} + +static void nextCodeLine() +{ + const char *fc = g_currentFontClass; + endCodeLine(); + if (g_yyLineNrcodify(sp); + nextCodeLine(); + } + else + { + g_code->codify(sp); + done=TRUE; + } + } +} + +static void startFontClass(const char *s) +{ + endFontClass(); + g_code->startFontClass(s); + g_currentFontClass=s; +} + +/*! counts the number of lines in the input */ +static int countLines() +{ + const char *p=g_inputString; + char c; + int count=1; + while ((c=*p)) + { + p++ ; + if (c=='\n') count++; + } + if (p>g_inputString && *(p-1)!='\n') + { // last line does not end with a \n, so we add an extra + // line and explicitly terminate the line after parsing. + count++, + g_needsTermination=TRUE; + } + return count; +} + +#undef YY_INPUT +#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); + +static int yyread(char *buf,int max_size) +{ + int c=0; + while( c < max_size && g_inputString[g_inputPosition] ) + { + *buf = g_inputString[g_inputPosition++] ; + c++; buf++; + } + return c; +} + +%} + +nl (\r\n|\r|\n) +ws [ \t]+ +open "<" +close ">" +namestart [A-Za-z\200-\377_] +namechar [:A-Za-z\200-\377_0-9.-] +esc "&#"[0-9]+";"|"&#x"[0-9a-fA-F]+";" +name {namestart}{namechar}* +comment {open}"!!--"([^-]|"-"[^-])*"--"{close} +data "random string" +string \"([^"&]|{esc})*\"|\'([^'&]|{esc})*\' + +%option noyywrap +%option nounput + +%% + +{ws} { + codifyLines(yytext); + } +"/" { + endFontClass(); + codify(yytext); + } +"=" { + endFontClass(); + codify(yytext); + } +{close} { + endFontClass(); + codify(yytext); + } +{name} { + startFontClass("keyword"); + codify(yytext); + endFontClass(); + } +{string} { + startFontClass("stringliteral"); + codifyLines(yytext); + endFontClass(); + } + +{open}{ws}?{name} { + // Write the < in a different color + char openBracket[] = { yytext[0], '\0' }; + codify(openBracket); + + // Then write the rest + yytext++; + startFontClass("keywordtype"); + codify(yytext); + endFontClass(); + + BEGIN(INITIAL); + } +{open}{ws}?"/"{name} { + // Write the "clearTooltips(); + + g_code = &od; + g_inputString = s; + g_inputPosition = 0; + g_currentFontClass = 0; + g_needsTermination = FALSE; + g_searchCtx=searchCtx; + + if (endLine!=-1) + g_inputLines = endLine+1; + else + g_inputLines = countLines(); + + if (startLine!=-1) + g_yyLineNr = startLine; + else + g_yyLineNr = 1; + + g_exampleName = exName; + g_sourceFileDef = fd; + + bool cleanupSourceDef = FALSE; + + if (fd==0) + { + // create a dummy filedef for the example + g_sourceFileDef = new FileDef("",(exName?exName:"generated")); + cleanupSourceDef = TRUE; + } + + if (g_sourceFileDef) + { + setCurrentDoc("l00001"); + } + + // Starts line 1 on the output + startCodeLine(); + + xmlcodeYYrestart( xmlcodeYYin ); + + xmlcodeYYlex(); + + if (g_needsTermination) + { + endCodeLine(); + } + if (fd) + { + TooltipManager::instance()->writeTooltips(*g_code); + } + if (cleanupSourceDef) + { + // delete the temporary file definition used for this example + delete g_sourceFileDef; + g_sourceFileDef=0; + } + + return; +} + +void resetXmlCodeParserState() +{ + g_currentDefinition = 0; + g_currentMemberDef = 0; +} + +#if !defined(YY_FLEX_SUBMINOR_VERSION) +extern "C" { // some bogus code to keep the compiler happy + void xmlcodeYYdummy() { yy_flex_realloc(0,0); } +} +#elif YY_FLEX_SUBMINOR_VERSION<33 +#error "You seem to be using a version of flex newer than 2.5.4. These are currently incompatible with 2.5.4, and do NOT work with doxygen! Please use version 2.5.4 or expect things to be parsed wrongly! A bug report has been submitted (#732132)." +#endif + diff --git a/winbuild/Doxygen.vcproj b/winbuild/Doxygen.vcproj index 03764f2..0c68a63 100644 --- a/winbuild/Doxygen.vcproj +++ b/winbuild/Doxygen.vcproj @@ -379,7 +379,7 @@ + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v0.12