summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWeston Thayer <weston@cryclops.com>2015-01-06 22:18:24 (GMT)
committerWeston Thayer <weston@cryclops.com>2015-01-06 22:18:24 (GMT)
commit62d24d83a13d3a8bf08b83e485358e4a7e5e226b (patch)
tree8f094b3ee7a5b82a0f18d52fb42760f0695482cc /src
parented39dab59f8af2c5b42cfac0b3140cf594412121 (diff)
downloadDoxygen-62d24d83a13d3a8bf08b83e485358e4a7e5e226b.zip
Doxygen-62d24d83a13d3a8bf08b83e485358e4a7e5e226b.tar.gz
Doxygen-62d24d83a13d3a8bf08b83e485358e4a7e5e226b.tar.bz2
Add support for basic XML syntax highlighting.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.in2
-rw-r--r--src/dbusxmlscanner.cpp43
-rw-r--r--src/libdoxygen.pro.in2
-rw-r--r--src/libdoxygen.t.in3
-rw-r--r--src/util.cpp2
-rw-r--r--src/xmlcode.h37
-rw-r--r--src/xmlcode.l411
7 files changed, 482 insertions, 18 deletions
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 <stdio.h>
+
+#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_yyLineNr<g_inputLines)
+ {
+ g_currentFontClass = fc;
+ startCodeLine();
+ }
+}
+
+static void codifyLines(char *text)
+{
+ char *p=text,*sp=p;
+ char c;
+ bool done=FALSE;
+
+ while (!done)
+ {
+ sp=p;
+
+ while ((c=*p++) && c!='\n') { }
+
+ if (c=='\n')
+ {
+ g_yyLineNr++;
+ *(p-1)='\0';
+ g_code->codify(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
+
+%%
+
+<INITIAL>{ws} {
+ codifyLines(yytext);
+ }
+<INITIAL>"/" {
+ endFontClass();
+ codify(yytext);
+ }
+<INITIAL>"=" {
+ endFontClass();
+ codify(yytext);
+ }
+<INITIAL>{close} {
+ endFontClass();
+ codify(yytext);
+ }
+<INITIAL>{name} {
+ startFontClass("keyword");
+ codify(yytext);
+ endFontClass();
+ }
+<INITIAL>{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 "</" in a different color
+ char closeBracket[] = { yytext[0], yytext[1], '\0' };
+ endFontClass();
+ codify(closeBracket);
+
+ // Then write the rest
+ yytext++; // skip the '<'
+ yytext++; // skip the '/'
+ startFontClass("keywordtype");
+ codify(yytext);
+ endFontClass();
+
+ BEGIN(INITIAL);
+ }
+{comment} {
+ // Strip off the extra '!'
+ yytext++; // <
+ *yytext = '<'; // replace '!' with '<'
+
+ startFontClass("comment");
+ codifyLines(yytext);
+ endFontClass();
+ }
+{nl} {
+ codifyLines(yytext);
+ }
+
+. {
+ //printf("!ERROR(%c)\n", *yytext);
+ codifyLines(yytext);
+ }
+
+%%
+
+void parseXmlCode(
+ CodeOutputInterface &od,
+ const char * /*className*/,
+ const QCString &s,
+ bool /*exBlock*/,
+ const char *exName,
+ FileDef *fd,
+ int startLine,
+ int endLine,
+ bool /*inlineFragment*/,
+ MemberDef *,
+ bool,Definition *searchCtx,
+ bool /*collectXRefs*/
+ )
+{
+ if (s.isEmpty()) return;
+
+ TooltipManager::instance()->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
+