Blame src/xmlcode.l

Packit Service 50c9f2
/******************************************************************************
Packit Service 50c9f2
 *
Packit Service 50c9f2
 * Copyright (C) 1997-2014 by Dimitri van Heesch.
Packit Service 50c9f2
 *
Packit Service 50c9f2
 * Permission to use, copy, modify, and distribute this software and its
Packit Service 50c9f2
 * documentation under the terms of the GNU General Public License is hereby 
Packit Service 50c9f2
 * granted. No representations are made about the suitability of this software 
Packit Service 50c9f2
 * for any purpose. It is provided "as is" without express or implied warranty.
Packit Service 50c9f2
 * See the GNU General Public License for more details.
Packit Service 50c9f2
 *
Packit Service 50c9f2
 * Documents produced by Doxygen are derivative works derived from the
Packit Service 50c9f2
 * input used in their production; they are not affected by this license.
Packit Service 50c9f2
 *
Packit Service 50c9f2
 */
Packit Service 50c9f2
/******************************************************************************
Packit Service 50c9f2
 * Parser for syntax highlighting and references for XML
Packit Service 50c9f2
 * written by Weston Thayer
Packit Service 50c9f2
 ******************************************************************************/
Packit Service 50c9f2
Packit Service 50c9f2
%option never-interactive
Packit Service 50c9f2
%option prefix="xmlcodeYY"
Packit Service 50c9f2
Packit Service 50c9f2
%{
Packit Service 50c9f2
Packit Service 50c9f2
#include <stdio.h>
Packit Service 50c9f2
Packit Service 50c9f2
#include "xmlcode.h"
Packit Service 50c9f2
Packit Service 50c9f2
#include "entry.h"
Packit Service 50c9f2
#include "doxygen.h"
Packit Service 50c9f2
#include "outputlist.h"
Packit Service 50c9f2
#include "util.h"
Packit Service 50c9f2
#include "membername.h"
Packit Service 50c9f2
#include "searchindex.h"
Packit Service 50c9f2
#include "config.h"
Packit Service 50c9f2
#include "filedef.h"
Packit Service 50c9f2
#include "tooltip.h"
Packit Service 50c9f2
Packit Service 50c9f2
#define YY_NEVER_INTERACTIVE 1
Packit Service 50c9f2
#define YY_NO_INPUT 1
Packit Service 50c9f2
#define YY_NO_UNISTD_H 1
Packit Service 50c9f2
Packit Service 50c9f2
static CodeOutputInterface * g_code;
Packit Service 50c9f2
static QCString      g_curClassName;
Packit Service 50c9f2
static QCString      g_parmType;
Packit Service 50c9f2
static QCString      g_parmName;
Packit Service 50c9f2
static const char *  g_inputString;     //!< the code fragment as text
Packit Service 50c9f2
static int           g_inputPosition;   //!< read offset during parsing 
Packit Service 50c9f2
static int           g_inputLines;      //!< number of line in the code fragment
Packit Service 50c9f2
static int           g_yyLineNr;        //!< current line number
Packit Service 50c9f2
static bool          g_needsTermination;
Packit Service 50c9f2
static Definition   *g_searchCtx;
Packit Service 50c9f2
Packit Service 50c9f2
static bool          g_exampleBlock;
Packit Service 50c9f2
static QCString      g_exampleName;
Packit Service 50c9f2
static QCString      g_exampleFile;
Packit Service 50c9f2
Packit Service 50c9f2
static QCString      g_type;
Packit Service 50c9f2
static QCString      g_name;
Packit Service 50c9f2
static QCString      g_args;
Packit Service 50c9f2
static QCString      g_classScope;
Packit Service 50c9f2
   
Packit Service 50c9f2
static QCString      g_CurrScope;
Packit Service 50c9f2
   
Packit Service 50c9f2
static FileDef *     g_sourceFileDef;
Packit Service 50c9f2
static Definition *  g_currentDefinition;
Packit Service 50c9f2
static MemberDef *   g_currentMemberDef;
Packit Service 50c9f2
static bool          g_includeCodeFragment;
Packit Service 50c9f2
static const char *  g_currentFontClass;
Packit Service 50c9f2
Packit Service 50c9f2
static void codify(const char* text) 
Packit Service 50c9f2
{ 
Packit Service 50c9f2
  g_code->codify(text);
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
static void setCurrentDoc(const QCString &anchor)
Packit Service 50c9f2
{
Packit Service 50c9f2
  if (Doxygen::searchIndex)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    if (g_searchCtx)
Packit Service 50c9f2
    {
Packit Service 50c9f2
      Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
Packit Service 50c9f2
    }
Packit Service 50c9f2
    else
Packit Service 50c9f2
    {
Packit Service 50c9f2
      Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*! start a new line of code, inserting a line number if g_sourceFileDef
Packit Service 50c9f2
 * is TRUE. If a definition starts at the current line, then the line
Packit Service 50c9f2
 * number is linked to the documentation of that definition.
Packit Service 50c9f2
 */
Packit Service 50c9f2
static void startCodeLine()
Packit Service 50c9f2
{
Packit Service 50c9f2
  if (g_sourceFileDef)
Packit Service 50c9f2
  {   
Packit Service 50c9f2
    Definition *d   = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
Packit Service 50c9f2
    
Packit Service 50c9f2
    if (!g_includeCodeFragment && d && d->isLinkableInProject())
Packit Service 50c9f2
    {
Packit Service 50c9f2
      g_currentDefinition = d;
Packit Service 50c9f2
      g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
Packit Service 50c9f2
      //g_insideBody = FALSE;
Packit Service 50c9f2
      g_classScope = d->name().copy();
Packit Service 50c9f2
      QCString lineAnchor;
Packit Service 50c9f2
      lineAnchor.sprintf("l%05d",g_yyLineNr);
Packit Service 50c9f2
      if (g_currentMemberDef)
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_code->writeLineNumber(g_currentMemberDef->getReference(),
Packit Service 50c9f2
                            g_currentMemberDef->getOutputFileBase(),
Packit Service 50c9f2
                            g_currentMemberDef->anchor(),g_yyLineNr);
Packit Service 50c9f2
        setCurrentDoc(lineAnchor);
Packit Service 50c9f2
      }
Packit Service 50c9f2
      else
Packit Service 50c9f2
      {
Packit Service 50c9f2
        g_code->writeLineNumber(d->getReference(),
Packit Service 50c9f2
                            d->getOutputFileBase(),
Packit Service 50c9f2
                            0,g_yyLineNr);
Packit Service 50c9f2
        setCurrentDoc(lineAnchor);
Packit Service 50c9f2
      }
Packit Service 50c9f2
    }
Packit Service 50c9f2
    else
Packit Service 50c9f2
    {
Packit Service 50c9f2
      g_code->writeLineNumber(0,0,0,g_yyLineNr);
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
  
Packit Service 50c9f2
  g_code->startCodeLine(g_sourceFileDef);
Packit Service 50c9f2
  
Packit Service 50c9f2
  if (g_currentFontClass)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    g_code->startFontClass(g_currentFontClass);
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
static void endFontClass()
Packit Service 50c9f2
{
Packit Service 50c9f2
  if (g_currentFontClass)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    g_code->endFontClass();
Packit Service 50c9f2
    g_currentFontClass=0;
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
static void endCodeLine()
Packit Service 50c9f2
{
Packit Service 50c9f2
  endFontClass();
Packit Service 50c9f2
  g_code->endCodeLine();
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
static void nextCodeLine()
Packit Service 50c9f2
{
Packit Service 50c9f2
  const char *fc = g_currentFontClass;
Packit Service 50c9f2
  endCodeLine();
Packit Service 50c9f2
  if (g_yyLineNr
Packit Service 50c9f2
  {
Packit Service 50c9f2
    g_currentFontClass = fc;
Packit Service 50c9f2
    startCodeLine();
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
static void codifyLines(char *text)
Packit Service 50c9f2
{
Packit Service 50c9f2
  char *p=text,*sp=p;
Packit Service 50c9f2
  char c;
Packit Service 50c9f2
  bool done=FALSE;
Packit Service 50c9f2
  
Packit Service 50c9f2
  while (!done)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    sp=p;
Packit Service 50c9f2
    
Packit Service 50c9f2
    while ((c=*p++) && c!='\n') { }
Packit Service 50c9f2
    
Packit Service 50c9f2
    if (c=='\n')
Packit Service 50c9f2
    {
Packit Service 50c9f2
      g_yyLineNr++;
Packit Service 50c9f2
      *(p-1)='\0';
Packit Service 50c9f2
      g_code->codify(sp);
Packit Service 50c9f2
      nextCodeLine();
Packit Service 50c9f2
    }
Packit Service 50c9f2
    else
Packit Service 50c9f2
    {
Packit Service 50c9f2
      g_code->codify(sp);
Packit Service 50c9f2
      done=TRUE;
Packit Service 50c9f2
    }
Packit Service 50c9f2
  }
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
static void startFontClass(const char *s)
Packit Service 50c9f2
{
Packit Service 50c9f2
  endFontClass();
Packit Service 50c9f2
  g_code->startFontClass(s);
Packit Service 50c9f2
  g_currentFontClass=s;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
/*! counts the number of lines in the input */
Packit Service 50c9f2
static int countLines()
Packit Service 50c9f2
{
Packit Service 50c9f2
  const char *p=g_inputString;
Packit Service 50c9f2
  char c;
Packit Service 50c9f2
  int count=1;
Packit Service 50c9f2
  while ((c=*p)) 
Packit Service 50c9f2
  { 
Packit Service 50c9f2
    p++ ; 
Packit Service 50c9f2
    if (c=='\n') count++;  
Packit Service 50c9f2
  }
Packit Service 50c9f2
  if (p>g_inputString && *(p-1)!='\n') 
Packit Service 50c9f2
  { // last line does not end with a \n, so we add an extra
Packit Service 50c9f2
    // line and explicitly terminate the line after parsing.
Packit Service 50c9f2
    count++, 
Packit Service 50c9f2
    g_needsTermination=TRUE; 
Packit Service 50c9f2
  } 
Packit Service 50c9f2
  return count;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
#undef YY_INPUT
Packit Service 50c9f2
#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
Packit Service 50c9f2
Packit Service 50c9f2
static int yyread(char *buf,int max_size)
Packit Service 50c9f2
{
Packit Service 50c9f2
  int c=0;
Packit Service 50c9f2
  while( c < max_size && g_inputString[g_inputPosition] )
Packit Service 50c9f2
  {
Packit Service 50c9f2
    *buf = g_inputString[g_inputPosition++] ;
Packit Service 50c9f2
    c++; buf++;
Packit Service 50c9f2
  }
Packit Service 50c9f2
  return c;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
%}
Packit Service 50c9f2
Packit Service 50c9f2
nl          (\r\n|\r|\n)
Packit Service 50c9f2
ws          [ \t]+
Packit Service 50c9f2
open        "<"
Packit Service 50c9f2
close       ">"
Packit Service 50c9f2
namestart   [A-Za-z\200-\377_]
Packit Service 50c9f2
namechar    [:A-Za-z\200-\377_0-9.-]
Packit Service 50c9f2
esc         "&#"[0-9]+";"|"&#x"[0-9a-fA-F]+";"
Packit Service 50c9f2
name        {namestart}{namechar}*
Packit Service 50c9f2
comment     {open}"!--"([^-]|"-"[^-])*"--"{close}
Packit Service 50c9f2
data        "random string"
Packit Service 50c9f2
string      \"([^"&]|{esc})*\"|\'([^'&]|{esc})*\'
Packit Service 50c9f2
 
Packit Service 50c9f2
%option noyywrap
Packit Service 50c9f2
%option nounput
Packit Service 50c9f2
Packit Service 50c9f2
%%
Packit Service 50c9f2
Packit Service 50c9f2
<INITIAL>{ws}       {
Packit Service 50c9f2
                        codifyLines(yytext);
Packit Service 50c9f2
                    }
Packit Service 50c9f2
<INITIAL>"/"        {
Packit Service 50c9f2
                        endFontClass();
Packit Service 50c9f2
                        codify(yytext);
Packit Service 50c9f2
                    }
Packit Service 50c9f2
<INITIAL>"="        {
Packit Service 50c9f2
                        endFontClass();
Packit Service 50c9f2
                        codify(yytext);
Packit Service 50c9f2
                    }
Packit Service 50c9f2
<INITIAL>{close}    {
Packit Service 50c9f2
                        endFontClass();
Packit Service 50c9f2
                        codify(yytext);
Packit Service 50c9f2
                    }
Packit Service 50c9f2
<INITIAL>{name}     {
Packit Service 50c9f2
                        startFontClass("keyword");
Packit Service 50c9f2
                        codify(yytext);
Packit Service 50c9f2
                        endFontClass();
Packit Service 50c9f2
                    }
Packit Service 50c9f2
<INITIAL>{string}   {
Packit Service 50c9f2
                        startFontClass("stringliteral");
Packit Service 50c9f2
                        codifyLines(yytext);
Packit Service 50c9f2
                        endFontClass();
Packit Service 50c9f2
                    }
Packit Service 50c9f2
                    
Packit Service 50c9f2
{open}{ws}?{name}   {
Packit Service 50c9f2
                        // Write the < in a different color
Packit Service 50c9f2
                        char openBracket[] = { yytext[0], '\0' };
Packit Service 50c9f2
                        codify(openBracket);
Packit Service 50c9f2
                        
Packit Service 50c9f2
                        // Then write the rest
Packit Service 50c9f2
                        yytext++;
Packit Service 50c9f2
                        startFontClass("keywordtype");
Packit Service 50c9f2
                        codify(yytext);
Packit Service 50c9f2
                        endFontClass();
Packit Service 50c9f2
                        
Packit Service 50c9f2
                        BEGIN(INITIAL);
Packit Service 50c9f2
                    }
Packit Service 50c9f2
{open}{ws}?"/"{name} {
Packit Service 50c9f2
                        // Write the "</" in a different color
Packit Service 50c9f2
                        char closeBracket[] = { yytext[0], yytext[1], '\0' };
Packit Service 50c9f2
                        endFontClass();
Packit Service 50c9f2
                        codify(closeBracket);
Packit Service 50c9f2
                        
Packit Service 50c9f2
                        // Then write the rest
Packit Service 50c9f2
                        yytext++; // skip the '<'
Packit Service 50c9f2
                        yytext++; // skip the '/'
Packit Service 50c9f2
                        startFontClass("keywordtype");
Packit Service 50c9f2
                        codify(yytext);
Packit Service 50c9f2
                        endFontClass();
Packit Service 50c9f2
Packit Service 50c9f2
                        BEGIN(INITIAL);
Packit Service 50c9f2
                    }
Packit Service 50c9f2
{comment}           {
Packit Service 50c9f2
                        // Strip off the extra '!'
Packit Service 50c9f2
                        // yytext++; // <
Packit Service 50c9f2
                        // *yytext = '<'; // replace '!' with '<'
Packit Service 50c9f2
Packit Service 50c9f2
                        startFontClass("comment");
Packit Service 50c9f2
                        codifyLines(yytext);
Packit Service 50c9f2
                        endFontClass();
Packit Service 50c9f2
                    }
Packit Service 50c9f2
{nl}                {
Packit Service 50c9f2
                        codifyLines(yytext);
Packit Service 50c9f2
                    }
Packit Service 50c9f2
Packit Service 50c9f2
.                   {
Packit Service 50c9f2
                        //printf("!ERROR(%c)\n", *yytext);
Packit Service 50c9f2
                        codifyLines(yytext);
Packit Service 50c9f2
                    }
Packit Service 50c9f2
Packit Service 50c9f2
%%
Packit Service 50c9f2
Packit Service 50c9f2
void parseXmlCode(
Packit Service 50c9f2
    CodeOutputInterface &od,
Packit Service 50c9f2
    const char * /*className*/,
Packit Service 50c9f2
    const QCString &s,
Packit Service 50c9f2
    bool exBlock,
Packit Service 50c9f2
    const char *exName,
Packit Service 50c9f2
    FileDef *fd,
Packit Service 50c9f2
    int startLine,
Packit Service 50c9f2
    int endLine,
Packit Service 50c9f2
    bool inlineFragment,
Packit Service 50c9f2
    MemberDef *,
Packit Service 50c9f2
    bool,Definition *searchCtx,
Packit Service 50c9f2
    bool /*collectXRefs*/
Packit Service 50c9f2
    ) 
Packit Service 50c9f2
{  
Packit Service 50c9f2
  if (s.isEmpty()) return;
Packit Service 50c9f2
  
Packit Service 50c9f2
  TooltipManager::instance()->clearTooltips();
Packit Service 50c9f2
  
Packit Service 50c9f2
  g_code = &od;
Packit Service 50c9f2
  g_inputString   = s;
Packit Service 50c9f2
  g_inputPosition = 0;
Packit Service 50c9f2
  g_currentFontClass = 0;
Packit Service 50c9f2
  g_needsTermination = FALSE;
Packit Service 50c9f2
  g_searchCtx=searchCtx;
Packit Service 50c9f2
  
Packit Service 50c9f2
  if (startLine!=-1)
Packit Service 50c9f2
    g_yyLineNr    = startLine;
Packit Service 50c9f2
  else
Packit Service 50c9f2
    g_yyLineNr    = 1;
Packit Service 50c9f2
  
Packit Service 50c9f2
  if (endLine!=-1)
Packit Service 50c9f2
    g_inputLines  = endLine+1;
Packit Service 50c9f2
  else
Packit Service 50c9f2
    g_inputLines  = g_yyLineNr + countLines() - 1;
Packit Service 50c9f2
  
Packit Service 50c9f2
  g_exampleBlock  = exBlock; 
Packit Service 50c9f2
  g_exampleName   = exName;
Packit Service 50c9f2
  g_sourceFileDef = fd;
Packit Service 50c9f2
Packit Service 50c9f2
  bool cleanupSourceDef = FALSE;
Packit Service 50c9f2
  
Packit Service 50c9f2
  if (exBlock && fd==0)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    // create a dummy filedef for the example
Packit Service 50c9f2
    g_sourceFileDef = new FileDef("",(exName?exName:"generated"));
Packit Service 50c9f2
    cleanupSourceDef = TRUE;
Packit Service 50c9f2
  }
Packit Service 50c9f2
  
Packit Service 50c9f2
  if (g_sourceFileDef) 
Packit Service 50c9f2
  {
Packit Service 50c9f2
    setCurrentDoc("l00001");
Packit Service 50c9f2
  }
Packit Service 50c9f2
Packit Service 50c9f2
  g_includeCodeFragment = inlineFragment;
Packit Service 50c9f2
  // Starts line 1 on the output  
Packit Service 50c9f2
  startCodeLine();
Packit Service 50c9f2
Packit Service 50c9f2
  xmlcodeYYrestart( xmlcodeYYin );
Packit Service 50c9f2
Packit Service 50c9f2
  xmlcodeYYlex();
Packit Service 50c9f2
Packit Service 50c9f2
  if (g_needsTermination)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    endCodeLine();
Packit Service 50c9f2
  }
Packit Service 50c9f2
  if (fd)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    TooltipManager::instance()->writeTooltips(*g_code);
Packit Service 50c9f2
  }
Packit Service 50c9f2
  if (cleanupSourceDef)
Packit Service 50c9f2
  {
Packit Service 50c9f2
    // delete the temporary file definition used for this example
Packit Service 50c9f2
    delete g_sourceFileDef;
Packit Service 50c9f2
    g_sourceFileDef=0;
Packit Service 50c9f2
  }
Packit Service 50c9f2
  
Packit Service 50c9f2
  return;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
void resetXmlCodeParserState() 
Packit Service 50c9f2
{
Packit Service 50c9f2
  g_currentDefinition = 0;
Packit Service 50c9f2
  g_currentMemberDef = 0;
Packit Service 50c9f2
}
Packit Service 50c9f2
Packit Service 50c9f2
#if !defined(YY_FLEX_SUBMINOR_VERSION) 
Packit Service 50c9f2
extern "C" { // some bogus code to keep the compiler happy
Packit Service 50c9f2
  void xmlcodeYYdummy() { yy_flex_realloc(0,0); } 
Packit Service 50c9f2
}
Packit Service 50c9f2
#elif YY_FLEX_MAJOR_VERSION<=2 && YY_FLEX_MINOR_VERSION<=5 && YY_FLEX_SUBMINOR_VERSION<33
Packit Service 50c9f2
#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)."
Packit Service 50c9f2
#endif
Packit Service 50c9f2