|
Packit |
1c1d7e |
/******************************************************************************
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Copyright (C) 1997-2015 by Dimitri van Heesch.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Permission to use, copy, modify, and distribute this software and its
|
|
Packit |
1c1d7e |
* documentation under the terms of the GNU General Public License is hereby
|
|
Packit |
1c1d7e |
* granted. No representations are made about the suitability of this software
|
|
Packit |
1c1d7e |
* for any purpose. It is provided "as is" without express or implied warranty.
|
|
Packit |
1c1d7e |
* See the GNU General Public License for more details.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
* Documents produced by Doxygen are derivative works derived from the
|
|
Packit |
1c1d7e |
* input used in their production; they are not affected by this license.
|
|
Packit |
1c1d7e |
*
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
/* This code is based on the work done by the MoxyPyDoxy team
|
|
Packit |
1c1d7e |
* (Linda Leong, Mike Rivera, Kim Truong, and Gabriel Estrada)
|
|
Packit |
1c1d7e |
* in Spring 2005 as part of CS 179E: Compiler Design Project
|
|
Packit |
1c1d7e |
* at the University of California, Riverside; the course was
|
|
Packit |
1c1d7e |
* taught by Peter H. Froehlich <phf@acm.org>.
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%option never-interactive
|
|
Packit |
1c1d7e |
%option prefix="pycodeYY"
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%{
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#include <stdio.h>
|
|
Packit |
1c1d7e |
#include <qvaluestack.h>
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#include "pycode.h"
|
|
Packit |
1c1d7e |
#include "message.h"
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#include "scanner.h"
|
|
Packit |
1c1d7e |
#include "entry.h"
|
|
Packit |
1c1d7e |
#include "doxygen.h"
|
|
Packit |
1c1d7e |
#include "outputlist.h"
|
|
Packit |
1c1d7e |
#include "util.h"
|
|
Packit |
1c1d7e |
#include "membername.h"
|
|
Packit |
1c1d7e |
#include "searchindex.h"
|
|
Packit |
1c1d7e |
#include "config.h"
|
|
Packit |
1c1d7e |
#include "groupdef.h"
|
|
Packit |
1c1d7e |
#include "classlist.h"
|
|
Packit |
1c1d7e |
#include "filedef.h"
|
|
Packit |
1c1d7e |
#include "namespacedef.h"
|
|
Packit |
1c1d7e |
#include "tooltip.h"
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// Toggle for some debugging info
|
|
Packit |
1c1d7e |
//#define DBG_CTX(x) fprintf x
|
|
Packit |
1c1d7e |
#define DBG_CTX(x) do { } while(0)
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#define YY_NO_INPUT 1
|
|
Packit |
1c1d7e |
#define YY_NO_UNISTD_H 1
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static ClassSDict g_codeClassSDict(17);
|
|
Packit |
1c1d7e |
static QCString g_curClassName;
|
|
Packit |
1c1d7e |
static QStrList g_curClassBases;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static CodeOutputInterface * g_code;
|
|
Packit |
1c1d7e |
static const char * g_inputString; //!< the code fragment as text
|
|
Packit |
1c1d7e |
static int g_inputPosition; //!< read offset during parsing
|
|
Packit |
1c1d7e |
static const char * g_currentFontClass;
|
|
Packit |
1c1d7e |
static bool g_needsTermination;
|
|
Packit |
1c1d7e |
static Definition *g_searchCtx;
|
|
Packit |
1c1d7e |
static bool g_collectXRefs;
|
|
Packit |
1c1d7e |
static int g_inputLines; //!< number of line in the code fragment
|
|
Packit |
1c1d7e |
static int g_yyLineNr; //!< current line number
|
|
Packit |
1c1d7e |
static FileDef * g_sourceFileDef;
|
|
Packit |
1c1d7e |
static Definition * g_currentDefinition;
|
|
Packit |
1c1d7e |
static MemberDef * g_currentMemberDef;
|
|
Packit |
1c1d7e |
static bool g_includeCodeFragment;
|
|
Packit |
1c1d7e |
static QCString g_realScope;
|
|
Packit |
1c1d7e |
//static bool g_insideBody;
|
|
Packit |
1c1d7e |
static int g_bodyCurlyCount;
|
|
Packit |
1c1d7e |
static bool g_searchingForBody;
|
|
Packit |
1c1d7e |
static QCString g_classScope;
|
|
Packit |
1c1d7e |
static int g_paramParens;
|
|
Packit |
1c1d7e |
//static int g_anchorCount;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static bool g_exampleBlock;
|
|
Packit |
1c1d7e |
static QCString g_exampleName;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static QCString g_type;
|
|
Packit |
1c1d7e |
static QCString g_name;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static bool g_doubleStringIsDoc;
|
|
Packit |
1c1d7e |
static bool g_doubleQuote;
|
|
Packit |
1c1d7e |
static bool g_noSuiteFound;
|
|
Packit |
1c1d7e |
static int g_stringContext;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static QValueStack<uint> g_indents; //!< Tracks indentation levels for scoping in python
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static QCString g_docBlock; //!< contents of all lines of a documentation block
|
|
Packit |
1c1d7e |
static bool g_endComment;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void endFontClass();
|
|
Packit |
1c1d7e |
static void adjustScopesAndSuites(unsigned indentLength);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! Represents a stack of variable to class mappings as found in the
|
|
Packit |
1c1d7e |
* code. Each scope is enclosed in pushScope() and popScope() calls.
|
|
Packit |
1c1d7e |
* Variables are added by calling addVariables() and one can search
|
|
Packit |
1c1d7e |
* for variable using findVariable().
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
class PyVariableContext
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
static const ClassDef *dummyContext;
|
|
Packit |
1c1d7e |
class Scope : public SDict<ClassDef>
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
Scope() : SDict<ClassDef>(17) {}
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
PyVariableContext()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_scopes.setAutoDelete(TRUE);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
virtual ~PyVariableContext()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void pushScope()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_scopes.append(new Scope);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void popScope()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (m_scopes.count()>0)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_scopes.remove(m_scopes.count()-1);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void clear()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_scopes.clear();
|
|
Packit |
1c1d7e |
m_globalScope.clear();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void clearExceptGlobal()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_scopes.clear();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void addVariable(const QCString &type,const QCString &name);
|
|
Packit |
1c1d7e |
ClassDef *findVariable(const QCString &name);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
private:
|
|
Packit |
1c1d7e |
Scope m_globalScope;
|
|
Packit |
1c1d7e |
QList<Scope> m_scopes;
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void PyVariableContext::addVariable(const QCString &type,const QCString &name)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("PyVariableContext::addVariable(%s,%s)\n",type.data(),name.data());
|
|
Packit |
1c1d7e |
QCString ltype = type.simplifyWhiteSpace();
|
|
Packit |
1c1d7e |
QCString lname = name.simplifyWhiteSpace();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast();
|
|
Packit |
1c1d7e |
ClassDef *varType;
|
|
Packit |
1c1d7e |
if (
|
|
Packit |
1c1d7e |
(varType=g_codeClassSDict[ltype]) || // look for class definitions inside the code block
|
|
Packit |
1c1d7e |
(varType=getResolvedClass(g_currentDefinition,g_sourceFileDef,ltype)) // look for global class definitions
|
|
Packit |
1c1d7e |
)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
scope->append(lname,varType); // add it to a list
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (m_scopes.count()>0) // for local variables add a dummy entry so the name
|
|
Packit |
1c1d7e |
// is hidden to avoid FALSE links to global variables with the same name
|
|
Packit |
1c1d7e |
// TODO: make this work for namespaces as well!
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
scope->append(lname,dummyContext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ClassDef *PyVariableContext::findVariable(const QCString &name)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (name.isEmpty()) return 0;
|
|
Packit |
1c1d7e |
ClassDef *result = 0;
|
|
Packit |
1c1d7e |
QListIterator<Scope> sli(m_scopes);
|
|
Packit |
1c1d7e |
Scope *scope;
|
|
Packit |
1c1d7e |
// search from inner to outer scope
|
|
Packit |
1c1d7e |
for (sli.toLast();(scope=sli.current());--sli)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
result = scope->find(name);
|
|
Packit |
1c1d7e |
if (result)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
return result;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
// nothing found -> also try the global scope
|
|
Packit |
1c1d7e |
result=m_globalScope.find(name);
|
|
Packit |
1c1d7e |
return result;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static PyVariableContext g_theVarContext;
|
|
Packit |
1c1d7e |
const ClassDef *PyVariableContext::dummyContext = (ClassDef*)0x8;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
class PyCallContext
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
public:
|
|
Packit |
1c1d7e |
struct Ctx
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Ctx() : name(g_name), type(g_type), cd(0) {}
|
|
Packit |
1c1d7e |
QCString name;
|
|
Packit |
1c1d7e |
QCString type;
|
|
Packit |
1c1d7e |
ClassDef *cd;
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
PyCallContext()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_classList.append(new Ctx);
|
|
Packit |
1c1d7e |
m_classList.setAutoDelete(TRUE);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
virtual ~PyCallContext() {}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void setClass(ClassDef *cd)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Ctx *ctx = m_classList.getLast();
|
|
Packit |
1c1d7e |
if (ctx)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ctx->cd=cd;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
void pushScope()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_classList.append(new Ctx);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void popScope()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (m_classList.count()>1)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Ctx *ctx = m_classList.getLast();
|
|
Packit |
1c1d7e |
if (ctx)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_name = ctx->name;
|
|
Packit |
1c1d7e |
g_type = ctx->type;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
m_classList.removeLast();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void clear()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
m_classList.clear();
|
|
Packit |
1c1d7e |
m_classList.append(new Ctx);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ClassDef *getClass() const
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Ctx *ctx = m_classList.getLast();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (ctx)
|
|
Packit |
1c1d7e |
return ctx->cd;
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
return 0;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
private:
|
|
Packit |
1c1d7e |
QList<Ctx> m_classList;
|
|
Packit |
1c1d7e |
};
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static PyCallContext g_theCallContext;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! counts the number of lines in the input */
|
|
Packit |
1c1d7e |
static int countLines()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
const char *p=g_inputString;
|
|
Packit |
1c1d7e |
char c;
|
|
Packit |
1c1d7e |
int count=1;
|
|
Packit |
1c1d7e |
while ((c=*p))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
p++ ;
|
|
Packit |
1c1d7e |
if (c=='\n') count++;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (p>g_inputString && *(p-1)!='\n')
|
|
Packit |
1c1d7e |
{ // last line does not end with a \n, so we add an extra
|
|
Packit |
1c1d7e |
// line and explicitly terminate the line after parsing.
|
|
Packit |
1c1d7e |
count++,
|
|
Packit |
1c1d7e |
g_needsTermination=TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return count;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void setCurrentDoc(const QCString &anchor)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (Doxygen::searchIndex)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (g_searchCtx)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void addToSearchIndex(const char *text)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (Doxygen::searchIndex)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Doxygen::searchIndex->addWord(text,FALSE);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static ClassDef *stripClassName(const char *s,Definition *d=g_currentDefinition)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int pos=0;
|
|
Packit |
1c1d7e |
QCString type = s;
|
|
Packit |
1c1d7e |
QCString className;
|
|
Packit |
1c1d7e |
QCString templSpec;
|
|
Packit |
1c1d7e |
while (extractClassNameFromType(type,pos,className,templSpec)!=-1)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QCString clName=className+templSpec;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ClassDef *cd=0;
|
|
Packit |
1c1d7e |
if (!g_classScope.isEmpty())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
cd=getResolvedClass(d,g_sourceFileDef,g_classScope+"::"+clName);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (cd==0)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
cd=getResolvedClass(d,g_sourceFileDef,clName);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (cd)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
return cd;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
return 0;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! start a new line of code, inserting a line number if g_sourceFileDef
|
|
Packit |
1c1d7e |
* is TRUE. If a definition starts at the current line, then the line
|
|
Packit |
1c1d7e |
* number is linked to the documentation of that definition.
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
static void startCodeLine()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//if (g_currentFontClass) { g_code->endFontClass(); }
|
|
Packit |
1c1d7e |
if (g_sourceFileDef)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//QCString lineNumber,lineAnchor;
|
|
Packit |
1c1d7e |
//lineNumber.sprintf("%05d",g_yyLineNr);
|
|
Packit |
1c1d7e |
//lineAnchor.sprintf("l%05d",g_yyLineNr);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
|
|
Packit |
1c1d7e |
//printf("startCodeLine %d d=%p\n",g_yyLineNr,d);
|
|
Packit |
1c1d7e |
//g_code->startLineNumber();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (!g_includeCodeFragment && d && d->isLinkableInProject())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_currentDefinition = d;
|
|
Packit |
1c1d7e |
g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
|
|
Packit |
1c1d7e |
//g_insideBody = FALSE;
|
|
Packit |
1c1d7e |
g_endComment = FALSE;
|
|
Packit |
1c1d7e |
g_searchingForBody = TRUE;
|
|
Packit |
1c1d7e |
g_realScope = d->name().copy();
|
|
Packit |
1c1d7e |
g_classScope = d->name().copy();
|
|
Packit |
1c1d7e |
//printf("Real scope: `%s'\n",g_realScope.data());
|
|
Packit |
1c1d7e |
g_bodyCurlyCount = 0;
|
|
Packit |
1c1d7e |
QCString lineAnchor;
|
|
Packit |
1c1d7e |
lineAnchor.sprintf("l%05d",g_yyLineNr);
|
|
Packit |
1c1d7e |
if (g_currentMemberDef)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_code->writeLineNumber(g_currentMemberDef->getReference(),
|
|
Packit |
1c1d7e |
g_currentMemberDef->getOutputFileBase(),
|
|
Packit |
1c1d7e |
g_currentMemberDef->anchor(),g_yyLineNr);
|
|
Packit |
1c1d7e |
setCurrentDoc(lineAnchor);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_code->writeLineNumber(d->getReference(),
|
|
Packit |
1c1d7e |
d->getOutputFileBase(),
|
|
Packit |
1c1d7e |
0,g_yyLineNr);
|
|
Packit |
1c1d7e |
setCurrentDoc(lineAnchor);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//g_code->codify(lineNumber);
|
|
Packit |
1c1d7e |
g_code->writeLineNumber(0,0,0,g_yyLineNr);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
//g_code->endLineNumber();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
g_code->startCodeLine(g_sourceFileDef);
|
|
Packit |
1c1d7e |
if (g_currentFontClass)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_code->startFontClass(g_currentFontClass);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void codify(const char* text)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_code->codify(text);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void endCodeLine()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
g_code->endCodeLine();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void nextCodeLine()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
const char *fc = g_currentFontClass;
|
|
Packit |
1c1d7e |
endCodeLine();
|
|
Packit |
1c1d7e |
if (g_yyLineNr
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_currentFontClass = fc;
|
|
Packit |
1c1d7e |
startCodeLine();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*! writes a link to a fragment \a text that may span multiple lines, inserting
|
|
Packit |
1c1d7e |
* line numbers for each line. If \a text contains newlines, the link will be
|
|
Packit |
1c1d7e |
* split into multiple links with the same destination, one for each line.
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
static void writeMultiLineCodeLink(CodeOutputInterface &ol,
|
|
Packit |
1c1d7e |
Definition *d,
|
|
Packit |
1c1d7e |
const char *text)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
|
|
Packit |
1c1d7e |
TooltipManager::instance()->addTooltip(d);
|
|
Packit |
1c1d7e |
QCString ref = d->getReference();
|
|
Packit |
1c1d7e |
QCString file = d->getOutputFileBase();
|
|
Packit |
1c1d7e |
QCString anchor = d->anchor();
|
|
Packit |
1c1d7e |
QCString tooltip;
|
|
Packit |
1c1d7e |
if (!sourceTooltips) // fall back to simple "title" tooltips
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
tooltip = d->briefDescriptionAsTooltip();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
bool done=FALSE;
|
|
Packit |
1c1d7e |
char *p=(char *)text;
|
|
Packit |
1c1d7e |
while (!done)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
char *sp=p;
|
|
Packit |
1c1d7e |
char c;
|
|
Packit |
1c1d7e |
while ((c=*p++) && c!='\n') { }
|
|
Packit |
1c1d7e |
if (c=='\n')
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_yyLineNr++;
|
|
Packit |
1c1d7e |
*(p-1)='\0';
|
|
Packit |
1c1d7e |
//printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
|
|
Packit |
1c1d7e |
ol.writeCodeLink(ref,file,anchor,sp,tooltip);
|
|
Packit |
1c1d7e |
nextCodeLine();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
|
|
Packit |
1c1d7e |
ol.writeCodeLink(ref,file,anchor,sp,tooltip);
|
|
Packit |
1c1d7e |
done=TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void startFontClass(const char *s)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
// if font class is already set don't stop and start it.
|
|
Packit |
1c1d7e |
// strcmp does not like null pointers as input.
|
|
Packit |
1c1d7e |
if (!g_currentFontClass || !s || strcmp(g_currentFontClass,s))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
g_code->startFontClass(s);
|
|
Packit |
1c1d7e |
g_currentFontClass=s;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void endFontClass()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (g_currentFontClass)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_code->endFontClass();
|
|
Packit |
1c1d7e |
g_currentFontClass=0;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void codifyLines(char *text)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
|
|
Packit |
1c1d7e |
char *p=text,*sp=p;
|
|
Packit |
1c1d7e |
char c;
|
|
Packit |
1c1d7e |
bool done=FALSE;
|
|
Packit |
1c1d7e |
const char * tmp_currentFontClass = g_currentFontClass;
|
|
Packit |
1c1d7e |
while (!done)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
sp=p;
|
|
Packit |
1c1d7e |
while ((c=*p++) && c!='\n') { }
|
|
Packit |
1c1d7e |
if (c=='\n')
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_yyLineNr++;
|
|
Packit |
1c1d7e |
*(p-1)='\0';
|
|
Packit |
1c1d7e |
g_code->codify(sp);
|
|
Packit |
1c1d7e |
endCodeLine();
|
|
Packit |
1c1d7e |
if (g_yyLineNr
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
startCodeLine();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (tmp_currentFontClass)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
startFontClass(tmp_currentFontClass);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_code->codify(sp);
|
|
Packit |
1c1d7e |
done=TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void codifyLines(const QCString &str)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
char *tmp= (char *)malloc(str.length()+1);
|
|
Packit |
1c1d7e |
qstrcpy(tmp, str);
|
|
Packit |
1c1d7e |
codifyLines(tmp);
|
|
Packit |
1c1d7e |
free(tmp);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static bool getLinkInScope(const QCString &c, // scope
|
|
Packit |
1c1d7e |
const QCString &m, // member
|
|
Packit |
1c1d7e |
const char *memberText, // exact text
|
|
Packit |
1c1d7e |
CodeOutputInterface &ol,
|
|
Packit |
1c1d7e |
const char *text
|
|
Packit |
1c1d7e |
)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
MemberDef *md;
|
|
Packit |
1c1d7e |
ClassDef *cd;
|
|
Packit |
1c1d7e |
FileDef *fd;
|
|
Packit |
1c1d7e |
NamespaceDef *nd;
|
|
Packit |
1c1d7e |
GroupDef *gd;
|
|
Packit |
1c1d7e |
//printf("Trying `%s'::`%s'\n",c.data(),m.data());
|
|
Packit |
1c1d7e |
if (getDefs(c,m,"()",md,cd,fd,nd,gd,FALSE,g_sourceFileDef) &&
|
|
Packit |
1c1d7e |
md->isLinkable())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//Definition *d=0;
|
|
Packit |
1c1d7e |
//if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
Definition *d = md->getOuterScope()==Doxygen::globalScope ?
|
|
Packit |
1c1d7e |
md->getBodyDef() : md->getOuterScope();
|
|
Packit |
1c1d7e |
//printf("Found! d=%s\n",d?d->name().data():"<none>");
|
|
Packit |
1c1d7e |
if (md->getGroupDef()) d = md->getGroupDef();
|
|
Packit |
1c1d7e |
if (d && d->isLinkable())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope()));
|
|
Packit |
1c1d7e |
//printf("g_currentDefinition=%p g_currentMemberDef=%p\n",
|
|
Packit |
1c1d7e |
// g_currentDefinition,g_currentMemberDef);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (g_currentDefinition && g_currentMemberDef &&
|
|
Packit |
1c1d7e |
md!=g_currentMemberDef && g_collectXRefs)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
addDocCrossReference(g_currentMemberDef,md);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
//printf("d->getReference()=`%s' d->getOutputBase()=`%s' name=`%s' member name=`%s'\n",d->getReference().data(),d->getOutputFileBase().data(),d->name().data(),md->name().data());
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
writeMultiLineCodeLink(ol,md, text ? text : memberText);
|
|
Packit |
1c1d7e |
addToSearchIndex(text ? text : memberText);
|
|
Packit |
1c1d7e |
return TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static bool getLink(const char *className,
|
|
Packit |
1c1d7e |
const char *memberName,
|
|
Packit |
1c1d7e |
CodeOutputInterface &ol,
|
|
Packit |
1c1d7e |
const char *text=0)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QCString m=removeRedundantWhiteSpace(memberName);
|
|
Packit |
1c1d7e |
QCString c=className;
|
|
Packit |
1c1d7e |
if (!getLinkInScope(c,m,memberName,ol,text))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (!g_curClassName.isEmpty())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (!c.isEmpty()) c.prepend("::");
|
|
Packit |
1c1d7e |
c.prepend(g_curClassName);
|
|
Packit |
1c1d7e |
return getLinkInScope(c,m,memberName,ol,text);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*
|
|
Packit |
1c1d7e |
For a given string in the source code,
|
|
Packit |
1c1d7e |
finds its class or global id and links to it.
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName,
|
|
Packit |
1c1d7e |
bool typeOnly=FALSE)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QCString className=clName;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// Don't do anything for empty text
|
|
Packit |
1c1d7e |
if (className.isEmpty()) return;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
DBG_CTX((stderr,"generateClassOrGlobalLink(className=%s)\n",className.data()));
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ClassDef *cd=0,*lcd=0; /** Class def that we may find */
|
|
Packit |
1c1d7e |
MemberDef *md=0; /** Member def that we may find */
|
|
Packit |
1c1d7e |
//bool isLocal=FALSE;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if ((lcd=g_theVarContext.findVariable(className))==0) // not a local variable
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Definition *d = g_currentDefinition;
|
|
Packit |
1c1d7e |
QCString scope = substitute(className,".","::");
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
cd = getResolvedClass(d,g_sourceFileDef,substitute(className,".","::"),&md);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
DBG_CTX((stderr,"d=%s g_sourceFileDef=%s\n",
|
|
Packit |
1c1d7e |
d?d->displayName().data():"<null>",
|
|
Packit |
1c1d7e |
g_currentDefinition?g_currentDefinition->displayName().data():"<null>"));
|
|
Packit |
1c1d7e |
DBG_CTX((stderr,"is found as a type %s\n",cd?cd->name().data():"<null>"));
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (cd==0 && md==0) // also see if it is variable or enum or enum value
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
NamespaceDef *nd = getResolvedNamespace(scope);
|
|
Packit |
1c1d7e |
if (nd)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
writeMultiLineCodeLink(ol,nd,clName);
|
|
Packit |
1c1d7e |
addToSearchIndex(className);
|
|
Packit |
1c1d7e |
return;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else if (getLink(g_classScope,clName,ol,clName))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
return;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (lcd!=PyVariableContext::dummyContext)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_theCallContext.setClass(lcd);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
//isLocal=TRUE;
|
|
Packit |
1c1d7e |
DBG_CTX((stderr,"is a local variable cd=%p!\n",cd));
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (cd && cd->isLinkable()) // is it a linkable class
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
writeMultiLineCodeLink(ol,cd,clName);
|
|
Packit |
1c1d7e |
addToSearchIndex(className);
|
|
Packit |
1c1d7e |
if (md)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
Definition *d = md->getOuterScope()==Doxygen::globalScope ?
|
|
Packit |
1c1d7e |
md->getBodyDef() : md->getOuterScope();
|
|
Packit |
1c1d7e |
if (md->getGroupDef()) d = md->getGroupDef();
|
|
Packit |
1c1d7e |
if (d && d->isLinkable() && md->isLinkable() &&
|
|
Packit |
1c1d7e |
g_currentMemberDef && g_collectXRefs)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
addDocCrossReference(g_currentMemberDef,md);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // not a class, maybe a global member
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int scopeEnd = className.findRev(".");
|
|
Packit |
1c1d7e |
if (scopeEnd!=-1 && !typeOnly) // name with explicit scope
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
QCString scope = substitute(className.left(scopeEnd),".","::");
|
|
Packit |
1c1d7e |
QCString locName = className.right(className.length()-scopeEnd-1);
|
|
Packit |
1c1d7e |
ClassDef *mcd = getClass(scope);
|
|
Packit |
1c1d7e |
DBG_CTX((stderr,"scope=%s locName=%s mcd=%p\n",scope.data(),locName.data(),mcd));
|
|
Packit |
1c1d7e |
if (mcd)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
MemberDef *md = mcd->getMemberByName(locName);
|
|
Packit |
1c1d7e |
if (md)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope()));
|
|
Packit |
1c1d7e |
writeMultiLineCodeLink(ol,md,clName);
|
|
Packit |
1c1d7e |
addToSearchIndex(className);
|
|
Packit |
1c1d7e |
Definition *d = md->getOuterScope()==Doxygen::globalScope ?
|
|
Packit |
1c1d7e |
md->getBodyDef() : md->getOuterScope();
|
|
Packit |
1c1d7e |
if (md->getGroupDef()) d = md->getGroupDef();
|
|
Packit |
1c1d7e |
if (d && d->isLinkable() && md->isLinkable() &&
|
|
Packit |
1c1d7e |
g_currentMemberDef && g_collectXRefs)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
addDocCrossReference(g_currentMemberDef,md);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // check namespace as well
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
NamespaceDef *mnd = getResolvedNamespace(scope);
|
|
Packit |
1c1d7e |
if (mnd)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
MemberDef *md=mnd->getMemberByName(locName);
|
|
Packit |
1c1d7e |
if (md)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("name=%s scope=%s\n",locName.data(),scope.data());
|
|
Packit |
1c1d7e |
g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope()));
|
|
Packit |
1c1d7e |
writeMultiLineCodeLink(ol,md,clName);
|
|
Packit |
1c1d7e |
addToSearchIndex(className);
|
|
Packit |
1c1d7e |
Definition *d = md->getOuterScope()==Doxygen::globalScope ?
|
|
Packit |
1c1d7e |
md->getBodyDef() : md->getOuterScope();
|
|
Packit |
1c1d7e |
if (md->getGroupDef()) d = md->getGroupDef();
|
|
Packit |
1c1d7e |
if (d && d->isLinkable() && md->isLinkable() &&
|
|
Packit |
1c1d7e |
g_currentMemberDef && g_collectXRefs)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
addDocCrossReference(g_currentMemberDef,md);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// nothing found, just write out the word
|
|
Packit |
1c1d7e |
codifyLines(clName);
|
|
Packit |
1c1d7e |
addToSearchIndex(clName);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*
|
|
Packit |
1c1d7e |
As of June 1, this function seems to work
|
|
Packit |
1c1d7e |
for file members, but scopes are not
|
|
Packit |
1c1d7e |
being correctly tracked for classes
|
|
Packit |
1c1d7e |
so it doesn't work for classes yet.
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
static void generateFunctionLink(CodeOutputInterface &ol,char *funcName)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//CodeClassDef *ccd=0;
|
|
Packit |
1c1d7e |
ClassDef *ccd=0;
|
|
Packit |
1c1d7e |
QCString locScope=g_classScope.copy();
|
|
Packit |
1c1d7e |
QCString locFunc=removeRedundantWhiteSpace(funcName);
|
|
Packit |
1c1d7e |
DBG_CTX((stdout,"*** locScope=%s locFunc=%s\n",locScope.data(),locFunc.data()));
|
|
Packit |
1c1d7e |
int i=locFunc.findRev("::");
|
|
Packit |
1c1d7e |
if (i>0)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
locScope=locFunc.left(i);
|
|
Packit |
1c1d7e |
locFunc=locFunc.right(locFunc.length()-i-2).stripWhiteSpace();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
//printf("generateFunctionLink(%s) classScope=`%s'\n",locFunc.data(),locScope.data());
|
|
Packit |
1c1d7e |
if (!locScope.isEmpty() && (ccd=g_codeClassSDict[locScope]))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("using classScope %s\n",g_classScope.data());
|
|
Packit |
1c1d7e |
if (ccd->baseClasses())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
BaseClassListIterator bcli(*ccd->baseClasses());
|
|
Packit |
1c1d7e |
for ( ; bcli.current() ; ++bcli)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (getLink(bcli.current()->classDef->name(),locFunc,ol,funcName))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
return;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (!getLink(locScope,locFunc,ol,funcName))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
generateClassOrGlobalLink(ol,funcName);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static bool findMemberLink(CodeOutputInterface &ol,Definition *sym,const char *symName)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("sym %s outerScope=%s equal=%d\n",
|
|
Packit |
1c1d7e |
// sym->name().data(),sym->getOuterScope()->name().data(),
|
|
Packit |
1c1d7e |
// sym->getOuterScope()==g_currentDefinition);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (sym->getOuterScope() &&
|
|
Packit |
1c1d7e |
sym->getOuterScope()->definitionType()==Definition::TypeClass &&
|
|
Packit |
1c1d7e |
g_currentDefinition->definitionType()==Definition::TypeClass)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ClassDef *cd = (ClassDef*)sym->getOuterScope();
|
|
Packit |
1c1d7e |
ClassDef *thisCd = (ClassDef *)g_currentDefinition;
|
|
Packit |
1c1d7e |
if (sym->definitionType()==Definition::TypeMember)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (g_currentMemberDef && g_collectXRefs)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
addDocCrossReference(g_currentMemberDef,(MemberDef*)sym);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
DBG_CTX((stderr,"cd=%s thisCd=%s\n",cd?cd->name().data():"<none>",thisCd?thisCd->name().data():"<none>"));
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// TODO: find the nearest base class in case cd is a base class of
|
|
Packit |
1c1d7e |
// thisCd
|
|
Packit |
1c1d7e |
if (cd==thisCd || (thisCd && thisCd->isBaseClass(cd,TRUE)))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
writeMultiLineCodeLink(ol,sym,symName);
|
|
Packit |
1c1d7e |
return TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static void findMemberLink(CodeOutputInterface &ol,char *symName)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
//printf("Member reference: %s scope=%s member=%s\n",
|
|
Packit |
1c1d7e |
// yytext,
|
|
Packit |
1c1d7e |
// g_currentDefinition?g_currentDefinition->name().data():"<none>",
|
|
Packit |
1c1d7e |
// g_currentMemberDef?g_currentMemberDef->name().data():"<none>"
|
|
Packit |
1c1d7e |
// );
|
|
Packit |
1c1d7e |
if (g_currentDefinition)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
DefinitionIntf *di = Doxygen::symbolMap->find(symName);
|
|
Packit |
1c1d7e |
if (di)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (di->definitionType()==DefinitionIntf::TypeSymbolList) // multiple symbols
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
DefinitionListIterator dli(*(DefinitionList*)di);
|
|
Packit |
1c1d7e |
Definition *sym;
|
|
Packit |
1c1d7e |
for (dli.toFirst();(sym=dli.current());++dli)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (findMemberLink(ol,sym,symName)) return;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // single symbol
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
if (findMemberLink(ol,(Definition*)di,symName)) return;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
//printf("sym %s not found\n",&yytext[5]);
|
|
Packit |
1c1d7e |
codify(symName);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#undef YY_INPUT
|
|
Packit |
1c1d7e |
#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
static int yyread(char *buf,int max_size)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
int c=0;
|
|
Packit |
1c1d7e |
while( c < max_size && g_inputString[g_inputPosition] )
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
*buf = g_inputString[g_inputPosition++] ;
|
|
Packit |
1c1d7e |
c++; buf++;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
return c;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
BB [ \t]+
|
|
Packit |
1c1d7e |
B [ \t]*
|
|
Packit |
1c1d7e |
NEWLINE \n
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
DIGIT [0-9]
|
|
Packit |
1c1d7e |
LETTER [A-Za-z\x80-\xFF]
|
|
Packit |
1c1d7e |
NONEMPTY [A-Za-z0-9_\x80-\xFF]
|
|
Packit |
1c1d7e |
EXPCHAR [#(){}\[\],:.%/\\=`*~|&<>!;+-]
|
|
Packit |
1c1d7e |
NONEMPTYEXP [^ \t\n:]
|
|
Packit |
1c1d7e |
PARAMNONEMPTY [^ \t\n():]
|
|
Packit |
1c1d7e |
IDENTIFIER ({LETTER}|"_")({LETTER}|{DIGIT}|"_")*
|
|
Packit |
1c1d7e |
BORDER ([^A-Za-z0-9])
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
POUNDCOMMENT "##"
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
TRISINGLEQUOTE "'''"
|
|
Packit |
1c1d7e |
TRIDOUBLEQUOTE "\"\"\""
|
|
Packit |
1c1d7e |
LONGSTRINGCHAR [^\\"']
|
|
Packit |
1c1d7e |
ESCAPESEQ ("\\")(.)
|
|
Packit |
1c1d7e |
LONGSTRINGITEM ({LONGSTRINGCHAR}|{ESCAPESEQ})
|
|
Packit |
1c1d7e |
SMALLQUOTE ("\"\""|"\""|"'"|"''")
|
|
Packit |
1c1d7e |
LONGSTRINGBLOCK ({LONGSTRINGITEM}+|{SMALLQUOTE})
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
SHORTSTRING ("'"{SHORTSTRINGITEM}*"'"|'"'{SHORTSTRINGITEM}*'"')
|
|
Packit |
1c1d7e |
SHORTSTRINGITEM ({SHORTSTRINGCHAR}|{ESCAPESEQ})
|
|
Packit |
1c1d7e |
SHORTSTRINGCHAR [^\\\n"]
|
|
Packit |
1c1d7e |
STRINGLITERAL {STRINGPREFIX}?( {SHORTSTRING} | {LONGSTRING})
|
|
Packit |
1c1d7e |
STRINGPREFIX ("r"|"u"|"ur"|"R"|"U"|"UR"|"Ur"|"uR")
|
|
Packit |
1c1d7e |
KEYWORD ("lambda"|"import"|"class"|"assert"|"as"|"from"|"global"|"def"|"True"|"False")
|
|
Packit |
1c1d7e |
FLOWKW ("or"|"and"|"is"|"not"|"print"|"for"|"in"|"if"|"try"|"except"|"yield"|"raise"|"break"|"continue"|"pass"|"if"|"return"|"while"|"elif"|"else"|"finally")
|
|
Packit |
1c1d7e |
QUOTES ("\""[^"]*"\"")
|
|
Packit |
1c1d7e |
SINGLEQUOTES ("'"[^']*"'")
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
LONGINTEGER {INTEGER}("l"|"L")
|
|
Packit |
1c1d7e |
INTEGER ({DECIMALINTEGER}|{OCTINTEGER}|{HEXINTEGER})
|
|
Packit |
1c1d7e |
DECIMALINTEGER ({NONZERODIGIT}{DIGIT}*|"0")
|
|
Packit |
1c1d7e |
OCTINTEGER "0"{OCTDIGIT}+
|
|
Packit |
1c1d7e |
HEXINTEGER "0"("x"|"X"){HEXDIGIT}+
|
|
Packit |
1c1d7e |
NONZERODIGIT [1-9]
|
|
Packit |
1c1d7e |
OCTDIGIT [0-7]
|
|
Packit |
1c1d7e |
HEXDIGIT ({DIGIT}|[a-f]|[A-F])
|
|
Packit |
1c1d7e |
FLOATNUMBER ({POINTFLOAT}|{EXPONENTFLOAT})
|
|
Packit |
1c1d7e |
POINTFLOAT ({INTPART}?{FRACTION}|{INTPART}".")
|
|
Packit |
1c1d7e |
EXPONENTFLOAT ({INTPART}|{POINTFLOAT}){EXPONENT}
|
|
Packit |
1c1d7e |
INTPART {DIGIT}+
|
|
Packit |
1c1d7e |
FRACTION "."{DIGIT}+
|
|
Packit |
1c1d7e |
EXPONENT ("e"|"E")("+"|"-")?{DIGIT}+
|
|
Packit |
1c1d7e |
IMAGNUMBER ({FLOATNUMBER}|{INTPART})("j"|"J")
|
|
Packit |
1c1d7e |
ATOM ({IDENTIFIER}|{LITERAL}|{ENCLOSURE})
|
|
Packit |
1c1d7e |
ENCLOSURE ({PARENTH_FORM}|{LIST_DISPLAY}|{DICT_DISPLAY}|{STRING_CONVERSION})
|
|
Packit |
1c1d7e |
LITERAL ({STRINGLITERAL}|{INTEGER}|{LONGINTEGER}|{FLOATNUMBER}|{IMAGNUMBER})
|
|
Packit |
1c1d7e |
PARENTH_FORM "("{EXPRESSION_LIST}?")"
|
|
Packit |
1c1d7e |
TEST ({AND_TEST}("or"{AND_TEST})*|{LAMBDA_FORM})
|
|
Packit |
1c1d7e |
TESTLIST {TEST}( ","{TEST})*","?
|
|
Packit |
1c1d7e |
LIST_DISPLAY "["{LISTMAKER}?"]"
|
|
Packit |
1c1d7e |
LISTMAKER {EXPRESSION}({LIST_FOR}|(","{EXPRESSION})*","?)
|
|
Packit |
1c1d7e |
LIST_ITER ({LIST_FOR}|{LIST_IF})
|
|
Packit |
1c1d7e |
LIST_FOR "for"{EXPRESSION_LIST}"in"{TESTLIST}{LIST_ITER}?
|
|
Packit |
1c1d7e |
LIST_IF "if"{TEST}{LIST_ITER}?
|
|
Packit |
1c1d7e |
DICT_DISPLAY "\{"{KEY_DATUM_LIST}?"\}"
|
|
Packit |
1c1d7e |
KEY_DATUM_LIST {KEY_DATUM}(","{KEY_DATUM})*","?
|
|
Packit |
1c1d7e |
KEY_DATUM {EXPRESSION}":"{EXPRESSION}
|
|
Packit |
1c1d7e |
STRING_CONVERSION "`"{EXPRESSION_LIST}"`"
|
|
Packit |
1c1d7e |
PRIMARY ({ATOM}|{ATTRIBUTEREF}|{SUBSCRIPTION}|{SLICING}|{CALL})
|
|
Packit |
1c1d7e |
ATTRIBUTEREF {PRIMARY}"."{IDENTIFIER}
|
|
Packit |
1c1d7e |
SUBSCRIPTION {PRIMARY}"["{EXPRESSION_LIST}"]"
|
|
Packit |
1c1d7e |
SLICING ({SIMPLE_SLICING}|{EXTENDED_SLICING})
|
|
Packit |
1c1d7e |
SIMPLE_SLICING {PRIMARY}"["{SHORT_SLICE}"]"
|
|
Packit |
1c1d7e |
EXTENDED_SLICING {PRIMARY}"["{SLICE_LIST}"]"
|
|
Packit |
1c1d7e |
SLICE_LIST {SLICE_ITEM}(","{SLICE_ITEM})*","?
|
|
Packit |
1c1d7e |
SLICE_ITEM ({EXPRESSION}|{PROPER_SLICE}|{ELLIPSIS})
|
|
Packit |
1c1d7e |
PROPER_SLICE ({SHORT_SLICE}|{LONG_SLICE})
|
|
Packit |
1c1d7e |
SHORT_SLICE {LOWER_BOUND}?":"{UPPER_BOUND}?
|
|
Packit |
1c1d7e |
LONG_SLICE {SHORT_SLICE}":"{STRIDE}?
|
|
Packit |
1c1d7e |
LOWER_BOUND {EXPRESSION}
|
|
Packit |
1c1d7e |
UPPER_BOUND {EXPRESSION}
|
|
Packit |
1c1d7e |
STRIDE {EXPRESSION}
|
|
Packit |
1c1d7e |
ELLIPSIS "..."
|
|
Packit |
1c1d7e |
CALL {PRIMARY}"("({ARGUMENT_LIST}","?)?")"
|
|
Packit |
1c1d7e |
ARGUMENT_LIST ({POSITIONAL_ARGUMENTS}(","{KEYWORD_ARGUMENTS})?(",""*"{EXPRESSION})?(",""**"{EXPRESSION})?|{KEYWORD_ARGUMENTS}(",""*"{EXPRESSION})?(",""**"{EXPRESSION})?|"*"{EXPRESSION}(",""**"{EXPRESSION})?|"**"{EXPRESSION})
|
|
Packit |
1c1d7e |
POSITIONAL_ARGUMENTS {EXPRESSION}(","{EXPRESSION})*
|
|
Packit |
1c1d7e |
KEYWORD_ARGUMENTS {KEYWORD_ITEM}(","{KEYWORD_ITEM})*
|
|
Packit |
1c1d7e |
KEYWORD_ITEM {IDENTIFIER}"="{EXPRESSION}
|
|
Packit |
1c1d7e |
POWER {PRIMARY}("**"{U_EXPR})?
|
|
Packit |
1c1d7e |
U_EXPR ({POWER}|"-"{U_EXPR}|"+"{U_EXPR}|"\~"{U_EXPR})
|
|
Packit |
1c1d7e |
M_EXPR ({U_EXPR}|{M_EXPR}"*"{U_EXPR}|{M_EXPR}"//"{U_EXPR}|{M_EXPR}"/"{U_EXPR}|{M_EXPR}"\%"{U_EXPR})
|
|
Packit |
1c1d7e |
A_EXPR ({M_EXPR}|{A_EXPR}"+"{M_EXPR}|{A_EXPR}"-"{M_EXPR}
|
|
Packit |
1c1d7e |
SHIFT_EXPR ({A_EXPR}|{SHIFT_EXPR}("<<"|">>"){A_EXPR})
|
|
Packit |
1c1d7e |
AND_EXPR ({SHIFT_EXPR}|{AND_EXPR}"\;SPMamp;"{SHIFT_EXPR}
|
|
Packit |
1c1d7e |
XOR_EXPR ({AND_EXPR}|{XOR_EXPR}"\textasciicircum"{AND_EXPR})
|
|
Packit |
1c1d7e |
OR_EXPR ({XOR_EXPR}|{OR_EXPR}"|"{ XOR_EXPR})
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
COMPARISON {OR_EXPR}({COMP_OPERATOR}{OR_EXPR})*
|
|
Packit |
1c1d7e |
COMP_OPERATOR ("<"|">"|"=="|">="|"<="|"<>"|"!="|"is""not"?|"not"?"in")
|
|
Packit |
1c1d7e |
EXPRESSION ({OR_TEST}|{LAMBDA_FORM})
|
|
Packit |
1c1d7e |
OR_TEST ({AND_TEST}|{OR_TEST}"or"{AND_TEST})
|
|
Packit |
1c1d7e |
AND_TEST ({NOT_TEST}|{AND_TEST}"and"{NOT_TEST})
|
|
Packit |
1c1d7e |
NOT_TEST ({COMPARISON}|"not"{NOT_TEST})
|
|
Packit |
1c1d7e |
LAMBDA_FORM "lambda"{PARAMETER_LIST}?":"{EXPRESSION}
|
|
Packit |
1c1d7e |
EXPRESSION_LIST {EXPRESSION}(","{EXPRESSION})*","?
|
|
Packit |
1c1d7e |
SIMPLE_STMT ({EXPRESSION_STMT}|{ASSERT_STMT}|{ASSIGNMENT_STMT}|{AUGMENTED_ASSIGNMENT_STMT}|{PASS_STMT}|{DEL_STMT}|{PRINT_STMT}|{RETURN_STMT}|{YIELD_STMT}|{RAISE_STMT}|{BREAK_STMT}|{CONTINUE_STMT}|{IMPORT_STMT}|{GLOBAL_STMT}|{EXEC_STMT})
|
|
Packit |
1c1d7e |
EXPRESSION_STMT {EXPRESSION_LIST}
|
|
Packit |
1c1d7e |
ASSERT_STMT "assert"{EXPRESSION}(","{EXPRESSION})?
|
|
Packit |
1c1d7e |
ASSIGNMENT_STMT ({TARGET_LIST}"=")+{EXPRESSION_LIST}
|
|
Packit |
1c1d7e |
TARGET_LIST {TARGET}(","{TARGET})*","?
|
|
Packit |
1c1d7e |
TARGET ({IDENTIFIER}|"("{TARGET_LIST}")"|"["{TARGET_LIST}"]"|{ATTRIBUTEREF}|{SUBSCRIPTION}|{SLICING})
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%option noyywrap
|
|
Packit |
1c1d7e |
%option stack
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%x Body
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%x FunctionDec
|
|
Packit |
1c1d7e |
%x FunctionParams
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%x ClassDec
|
|
Packit |
1c1d7e |
%x ClassInheritance
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%x Suite
|
|
Packit |
1c1d7e |
%x SuiteCaptureIndent
|
|
Packit |
1c1d7e |
%x SuiteStart
|
|
Packit |
1c1d7e |
%x SuiteMaintain
|
|
Packit |
1c1d7e |
%x SuiteContinuing
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%x LongString
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%x SingleQuoteString
|
|
Packit |
1c1d7e |
%x DoubleQuoteString
|
|
Packit |
1c1d7e |
%x TripleString
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
%x DocBlock
|
|
Packit |
1c1d7e |
%%
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<Body,Suite>{
|
|
Packit |
1c1d7e |
"def"{BB} {
|
|
Packit |
1c1d7e |
startFontClass("keyword");
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
BEGIN( FunctionDec );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
"class"{BB} {
|
|
Packit |
1c1d7e |
startFontClass("keyword");
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
BEGIN( ClassDec );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"None" {
|
|
Packit |
1c1d7e |
startFontClass("keywordtype");
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"self."{IDENTIFIER}/"."({IDENTIFIER}".")*{IDENTIFIER}"(" {
|
|
Packit |
1c1d7e |
codify("self.");
|
|
Packit |
1c1d7e |
findMemberLink(*g_code,&yytext[5]);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"self."{IDENTIFIER}/"(" {
|
|
Packit |
1c1d7e |
codify("self.");
|
|
Packit |
1c1d7e |
findMemberLink(*g_code,&yytext[5]);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"self."{IDENTIFIER}/"."({IDENTIFIER}".")*{IDENTIFIER} {
|
|
Packit |
1c1d7e |
codify("self.");
|
|
Packit |
1c1d7e |
findMemberLink(*g_code,&yytext[5]);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"self."{IDENTIFIER} {
|
|
Packit |
1c1d7e |
codify("self.");
|
|
Packit |
1c1d7e |
findMemberLink(*g_code,&yytext[5]);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"cls."{IDENTIFIER}/"."({IDENTIFIER}".")*{IDENTIFIER}"(" {
|
|
Packit |
1c1d7e |
codify("cls.");
|
|
Packit |
1c1d7e |
findMemberLink(*g_code,&yytext[4]);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"cls."{IDENTIFIER}/"(" {
|
|
Packit |
1c1d7e |
codify("cls.");
|
|
Packit |
1c1d7e |
findMemberLink(*g_code,&yytext[4]);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"cls."{IDENTIFIER}/"."({IDENTIFIER}".")*{IDENTIFIER} {
|
|
Packit |
1c1d7e |
codify("cls.");
|
|
Packit |
1c1d7e |
findMemberLink(*g_code,&yytext[4]);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"cls."{IDENTIFIER} {
|
|
Packit |
1c1d7e |
codify("cls.");
|
|
Packit |
1c1d7e |
findMemberLink(*g_code,&yytext[4]);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<ClassDec>{IDENTIFIER} {
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
generateClassOrGlobalLink(*g_code,yytext);
|
|
Packit |
1c1d7e |
// codify(yytext);
|
|
Packit |
1c1d7e |
g_curClassName = yytext;
|
|
Packit |
1c1d7e |
g_curClassBases.clear();
|
|
Packit |
1c1d7e |
BEGIN( ClassInheritance );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<ClassInheritance>{
|
|
Packit |
1c1d7e |
({BB}|[(,)]) {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
({IDENTIFIER}".")*{IDENTIFIER} {
|
|
Packit |
1c1d7e |
// The parser
|
|
Packit |
1c1d7e |
// is assuming
|
|
Packit |
1c1d7e |
// that ALL identifiers
|
|
Packit |
1c1d7e |
// in this state
|
|
Packit |
1c1d7e |
// are base classes;
|
|
Packit |
1c1d7e |
// it doesn't check to see
|
|
Packit |
1c1d7e |
// that the first parenthesis
|
|
Packit |
1c1d7e |
// has been seen.
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// This is bad - it should
|
|
Packit |
1c1d7e |
// probably be more strict
|
|
Packit |
1c1d7e |
// about what to accept.
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
g_curClassBases.inSort(yytext);
|
|
Packit |
1c1d7e |
generateClassOrGlobalLink(*g_code,yytext);
|
|
Packit |
1c1d7e |
// codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
":" {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// Assume this will
|
|
Packit |
1c1d7e |
// be a one-line suite;
|
|
Packit |
1c1d7e |
// found counter-example
|
|
Packit |
1c1d7e |
// in SuiteStart.
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// Push a class scope
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
ClassDef *classDefToAdd = new ClassDef("",1,1,g_curClassName,ClassDef::Class,0,0,FALSE);
|
|
Packit |
1c1d7e |
g_codeClassSDict.append(g_curClassName,classDefToAdd);
|
|
Packit |
1c1d7e |
char *s=g_curClassBases.first();
|
|
Packit |
1c1d7e |
while (s)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
ClassDef *baseDefToAdd;
|
|
Packit |
1c1d7e |
baseDefToAdd=g_codeClassSDict[s];
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// Try to find class in global
|
|
Packit |
1c1d7e |
// scope
|
|
Packit |
1c1d7e |
if (baseDefToAdd==0)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
baseDefToAdd=getResolvedClass(g_currentDefinition,g_sourceFileDef,s);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (baseDefToAdd && baseDefToAdd!=classDefToAdd)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
classDefToAdd->insertBaseClass(baseDefToAdd,s,Public,Normal);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
s=g_curClassBases.next();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// Reset class-parsing variables.
|
|
Packit |
1c1d7e |
g_curClassName.resize(0);
|
|
Packit |
1c1d7e |
g_curClassBases.clear();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
g_noSuiteFound = TRUE;
|
|
Packit |
1c1d7e |
BEGIN( SuiteStart );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<FunctionDec>{
|
|
Packit |
1c1d7e |
{IDENTIFIER} {
|
|
Packit |
1c1d7e |
generateFunctionLink(*g_code,yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
{B}"(" {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
BEGIN( FunctionParams );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<FunctionParams>{
|
|
Packit |
1c1d7e |
({BB}|",") {
|
|
Packit |
1c1d7e |
// Parses delimiters
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
({IDENTIFIER}|{PARAMNONEMPTY}+) {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
")" {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
"\n" {
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
":" {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// Assume this will
|
|
Packit |
1c1d7e |
// be a one-line suite;
|
|
Packit |
1c1d7e |
// found counter-example
|
|
Packit |
1c1d7e |
// in SuiteStart.
|
|
Packit |
1c1d7e |
g_noSuiteFound = TRUE;
|
|
Packit |
1c1d7e |
BEGIN( SuiteStart );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<Body,Suite>{
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
{KEYWORD} {
|
|
Packit |
1c1d7e |
// Position-sensitive rules!
|
|
Packit |
1c1d7e |
// Must come AFTER keyword-triggered rules
|
|
Packit |
1c1d7e |
// Must come BEFORE identifier NONEMPTY-like rules
|
|
Packit |
1c1d7e |
// to syntax highlight.
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
startFontClass("keyword");
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
{FLOWKW} {
|
|
Packit |
1c1d7e |
startFontClass("keywordflow");
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
({IDENTIFIER}".")*{IDENTIFIER}/"(" {
|
|
Packit |
1c1d7e |
generateClassOrGlobalLink(*g_code,yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
({IDENTIFIER}".")+{IDENTIFIER} {
|
|
Packit |
1c1d7e |
generateClassOrGlobalLink(*g_code,yytext,TRUE);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
{IDENTIFIER} { codify(yytext); }
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<SuiteStart>{
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
{BB} {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"pass" {
|
|
Packit |
1c1d7e |
startFontClass("keyword");
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
BEGIN(Body);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
{KEYWORD} {
|
|
Packit |
1c1d7e |
startFontClass("keyword");
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// No indentation necessary
|
|
Packit |
1c1d7e |
g_noSuiteFound = FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
{FLOWKW} {
|
|
Packit |
1c1d7e |
startFontClass("keywordflow");
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// No indentation necessary
|
|
Packit |
1c1d7e |
g_noSuiteFound = FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
{IDENTIFIER} {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
{POUNDCOMMENT} {
|
|
Packit |
1c1d7e |
if (YY_START==SingleQuoteString ||
|
|
Packit |
1c1d7e |
YY_START==DoubleQuoteString ||
|
|
Packit |
1c1d7e |
YY_START==TripleString
|
|
Packit |
1c1d7e |
)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
REJECT;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
yy_push_state(YY_START);
|
|
Packit |
1c1d7e |
BEGIN(DocBlock);
|
|
Packit |
1c1d7e |
g_docBlock=yytext;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
{NEWLINE} {
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
if ( g_noSuiteFound )
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
// printf("New suite to capture! [%d]\n", g_yyLineNr);
|
|
Packit |
1c1d7e |
BEGIN ( SuiteCaptureIndent );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<SuiteCaptureIndent>{
|
|
Packit |
1c1d7e |
"\n"|({BB}"\n") {
|
|
Packit |
1c1d7e |
// Blankline - ignore, keep looking for indentation.
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
{BB} {
|
|
Packit |
1c1d7e |
// This state lasts momentarily,
|
|
Packit |
1c1d7e |
// to check the indentation
|
|
Packit |
1c1d7e |
// level that is about to be
|
|
Packit |
1c1d7e |
// used.
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
g_indents.push(yyleng);
|
|
Packit |
1c1d7e |
// printf("Captured indent of %d [line %d]\n", yyleng, g_yyLineNr);
|
|
Packit |
1c1d7e |
BEGIN( Suite );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<SuiteMaintain>{
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
{BB}/({NONEMPTY}|{EXPCHAR}) {
|
|
Packit |
1c1d7e |
// This implements poor
|
|
Packit |
1c1d7e |
// indendation-tracking;
|
|
Packit |
1c1d7e |
// should be improved.
|
|
Packit |
1c1d7e |
// (translate tabs to space, etc)
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
adjustScopesAndSuites((int)yyleng);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
"\n"|({BB}"\n") {
|
|
Packit |
1c1d7e |
// If this ever succeeds,
|
|
Packit |
1c1d7e |
// it means that this is
|
|
Packit |
1c1d7e |
// a blank line, and
|
|
Packit |
1c1d7e |
// can be ignored.
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
""/({NONEMPTY}|{EXPCHAR}) {
|
|
Packit |
1c1d7e |
// Default rule; matches
|
|
Packit |
1c1d7e |
// the empty string, assuming
|
|
Packit |
1c1d7e |
// real text starts here.
|
|
Packit |
1c1d7e |
// Just go straight to Body.
|
|
Packit |
1c1d7e |
adjustScopesAndSuites(0);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<Suite>{NEWLINE} {
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
BEGIN( SuiteMaintain );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Body>{IDENTIFIER} {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<Body>{NEWLINE} {
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<SingleQuoteString>{ // Single quoted string like 'That\'s a """nice""" string!'
|
|
Packit |
1c1d7e |
\\{B}\n { // line continuation
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
\\. { // espaced char
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
{STRINGPREFIX}?{TRIDOUBLEQUOTE} { // tripple double quotes
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"'" { // end of the string
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
BEGIN(g_stringContext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
[^"'\n\\]+ { // normal chars
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
. { // normal char
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<DoubleQuoteString>{ // Double quoted string like "That's \"a '''nice'''\" string!"
|
|
Packit |
1c1d7e |
\\{B}\n { // line continuation
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
\\. { // espaced char
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
{STRINGPREFIX}?{TRISINGLEQUOTE} { // tripple single quotes
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
"\"" { // end of the string
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
BEGIN(g_stringContext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
[^"'\n\\]+ { // normal chars
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
. { // normal char
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<TripleString>{
|
|
Packit |
1c1d7e |
{TRIDOUBLEQUOTE} |
|
|
Packit |
1c1d7e |
{TRISINGLEQUOTE} {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
if (g_doubleQuote==(yytext[0]=='"'))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
BEGIN(g_stringContext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
{LONGSTRINGBLOCK} {
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
\n {
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
. {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*
|
|
Packit |
1c1d7e |
<*>({NONEMPTY}|{EXPCHAR}|{BB}) { // This should go one character at a time.
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
// printf("[pycode] '%s' [ state %d ] [line %d] no match\n",
|
|
Packit |
1c1d7e |
// yytext, YY_START, g_yyLineNr);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//endFontClass();
|
|
Packit |
1c1d7e |
BEGIN(Body);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<*>{STRINGPREFIX}?{TRISINGLEQUOTE} |
|
|
Packit |
1c1d7e |
<*>{STRINGPREFIX}?{TRIDOUBLEQUOTE} {
|
|
Packit |
1c1d7e |
startFontClass("stringliteral");
|
|
Packit |
1c1d7e |
g_stringContext=YY_START;
|
|
Packit |
1c1d7e |
g_doubleQuote=yytext[yyleng-1]=='"';
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
BEGIN(TripleString);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<*>{STRINGPREFIX}?"'" { // single quoted string
|
|
Packit |
1c1d7e |
startFontClass("stringliteral");
|
|
Packit |
1c1d7e |
g_stringContext=YY_START;
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
BEGIN(SingleQuoteString);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<*>{STRINGPREFIX}?"\"" { // double quoted string
|
|
Packit |
1c1d7e |
startFontClass("stringliteral");
|
|
Packit |
1c1d7e |
g_stringContext=YY_START;
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
BEGIN(DoubleQuoteString);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<DocBlock>.* { // contents of current comment line
|
|
Packit |
1c1d7e |
g_docBlock+=yytext;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<DocBlock>"\n"{B}("#") { // comment block (next line is also comment line)
|
|
Packit |
1c1d7e |
g_docBlock+=yytext;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<DocBlock>{NEWLINE} { // comment block ends at the end of this line
|
|
Packit |
1c1d7e |
// remove special comment (default config)
|
|
Packit |
1c1d7e |
if (Config_getBool(STRIP_CODE_COMMENTS))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_yyLineNr+=((QCString)g_docBlock).contains('\n');
|
|
Packit |
1c1d7e |
g_endComment=TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else // do not remove comment
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
startFontClass("comment");
|
|
Packit |
1c1d7e |
codifyLines(g_docBlock);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
unput(*yytext);
|
|
Packit |
1c1d7e |
yy_pop_state();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<*>{POUNDCOMMENT}.* {
|
|
Packit |
1c1d7e |
if (YY_START==SingleQuoteString ||
|
|
Packit |
1c1d7e |
YY_START==DoubleQuoteString ||
|
|
Packit |
1c1d7e |
YY_START==TripleString
|
|
Packit |
1c1d7e |
)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
REJECT;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
yy_push_state(YY_START);
|
|
Packit |
1c1d7e |
BEGIN(DocBlock);
|
|
Packit |
1c1d7e |
g_docBlock=yytext;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<*>"#".* { // normal comment
|
|
Packit |
1c1d7e |
if (YY_START==SingleQuoteString ||
|
|
Packit |
1c1d7e |
YY_START==DoubleQuoteString ||
|
|
Packit |
1c1d7e |
YY_START==TripleString
|
|
Packit |
1c1d7e |
)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
REJECT;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
startFontClass("comment");
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<*>{NEWLINE} {
|
|
Packit |
1c1d7e |
if (g_endComment)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_endComment=FALSE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
codifyLines(yytext);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
//printf("[pycode] %d NEWLINE [line %d] no match\n",
|
|
Packit |
1c1d7e |
// YY_START, g_yyLineNr);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//endFontClass();
|
|
Packit |
1c1d7e |
BEGIN(Body);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<*>[ \t]+ {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
BEGIN(Body);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
<*>. {
|
|
Packit |
1c1d7e |
codify(yytext);
|
|
Packit |
1c1d7e |
// printf("[pycode] '%s' [ state %d ] [line %d] no match\n",
|
|
Packit |
1c1d7e |
// yytext, YY_START, g_yyLineNr);
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//endFontClass();
|
|
Packit |
1c1d7e |
BEGIN(Body);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
<*><<EOF>> {
|
|
Packit |
1c1d7e |
if (YY_START == DocBlock) {
|
|
Packit |
1c1d7e |
if (!Config_getBool(STRIP_CODE_COMMENTS))
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
startFontClass("comment");
|
|
Packit |
1c1d7e |
codifyLines(g_docBlock);
|
|
Packit |
1c1d7e |
endFontClass();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
yyterminate();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
%%
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*@ ----------------------------------------------------------------------------
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void resetPythonCodeParserState()
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
g_currentDefinition = 0;
|
|
Packit |
1c1d7e |
g_currentMemberDef = 0;
|
|
Packit |
1c1d7e |
g_doubleStringIsDoc = FALSE;
|
|
Packit |
1c1d7e |
g_paramParens = 0;
|
|
Packit |
1c1d7e |
g_indents.clear();
|
|
Packit |
1c1d7e |
BEGIN( Body );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
/*!
|
|
Packit |
1c1d7e |
Examines current stack of white-space indentations;
|
|
Packit |
1c1d7e |
re-syncs the parser with the correct scope.
|
|
Packit |
1c1d7e |
*/
|
|
Packit |
1c1d7e |
static void adjustScopesAndSuites(unsigned indentLength)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
// States to pop
|
|
Packit |
1c1d7e |
if (!g_indents.isEmpty() && indentLength < g_indents.top())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
while (!g_indents.isEmpty() && indentLength < g_indents.top())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
// printf("Exited scope indent of [%d]\n", g_indents.top());
|
|
Packit |
1c1d7e |
g_indents.pop(); // Pop the old suite's indentation
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
g_currentMemberDef=0;
|
|
Packit |
1c1d7e |
if (g_currentDefinition)
|
|
Packit |
1c1d7e |
g_currentDefinition=g_currentDefinition->getOuterScope();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
// Are there any remaining indentation levels for suites?
|
|
Packit |
1c1d7e |
if (!g_indents.isEmpty())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
BEGIN( Suite );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
BEGIN( Body );
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
void parsePythonCode(CodeOutputInterface &od,const char * /*className*/,
|
|
Packit |
1c1d7e |
const QCString &s,bool exBlock, const char *exName,
|
|
Packit |
1c1d7e |
FileDef *fd,int startLine,int endLine,bool inlineFragment,
|
|
Packit |
1c1d7e |
MemberDef *,bool,Definition *searchCtx,bool collectXRefs)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//printf("***parseCode()\n");
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
//--------------------------------------
|
|
Packit |
1c1d7e |
if (s.isEmpty()) return;
|
|
Packit |
1c1d7e |
printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL);
|
|
Packit |
1c1d7e |
TooltipManager::instance()->clearTooltips();
|
|
Packit |
1c1d7e |
g_code = &od;
|
|
Packit |
1c1d7e |
g_inputString = s;
|
|
Packit |
1c1d7e |
g_inputPosition = 0;
|
|
Packit |
1c1d7e |
g_currentFontClass = 0;
|
|
Packit |
1c1d7e |
g_needsTermination = FALSE;
|
|
Packit |
1c1d7e |
g_searchCtx=searchCtx;
|
|
Packit |
1c1d7e |
g_collectXRefs=collectXRefs;
|
|
Packit |
1c1d7e |
if (startLine!=-1)
|
|
Packit |
1c1d7e |
g_yyLineNr = startLine;
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
g_yyLineNr = 1;
|
|
Packit |
1c1d7e |
if (endLine!=-1)
|
|
Packit |
1c1d7e |
g_inputLines = endLine+1;
|
|
Packit |
1c1d7e |
else
|
|
Packit |
1c1d7e |
g_inputLines = g_yyLineNr + countLines() - 1;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
g_exampleBlock = exBlock;
|
|
Packit |
1c1d7e |
g_exampleName = exName;
|
|
Packit |
1c1d7e |
g_sourceFileDef = fd;
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
bool cleanupSourceDef = FALSE;
|
|
Packit |
1c1d7e |
if (exBlock && fd==0)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
// create a dummy filedef for the example
|
|
Packit |
1c1d7e |
g_sourceFileDef = new FileDef("",(exName?exName:"generated"));
|
|
Packit |
1c1d7e |
cleanupSourceDef = TRUE;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (g_sourceFileDef)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
setCurrentDoc("l00001");
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
g_includeCodeFragment = inlineFragment;
|
|
Packit |
1c1d7e |
// Starts line 1 on the output
|
|
Packit |
1c1d7e |
startCodeLine();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
pycodeYYrestart( pycodeYYin );
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
pycodeYYlex();
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (!g_indents.isEmpty())
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
// printf("Exited pysourceparser in inconsistent state!\n");
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
if (g_needsTermination)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
endCodeLine();
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (fd)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
TooltipManager::instance()->writeTooltips(*g_code);
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
if (cleanupSourceDef)
|
|
Packit |
1c1d7e |
{
|
|
Packit |
1c1d7e |
// delete the temporary file definition used for this example
|
|
Packit |
1c1d7e |
delete g_sourceFileDef;
|
|
Packit |
1c1d7e |
g_sourceFileDef=0;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL);
|
|
Packit |
1c1d7e |
return;
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
|
|
Packit |
1c1d7e |
#if !defined(YY_FLEX_SUBMINOR_VERSION)
|
|
Packit |
1c1d7e |
extern "C" { // some bogus code to keep the compiler happy
|
|
Packit |
1c1d7e |
void pycodeYYdummy() { yy_flex_realloc(0,0); }
|
|
Packit |
1c1d7e |
}
|
|
Packit |
1c1d7e |
#elif YY_FLEX_MAJOR_VERSION<=2 && YY_FLEX_MINOR_VERSION<=5 && YY_FLEX_SUBMINOR_VERSION<33
|
|
Packit |
1c1d7e |
#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 |
1c1d7e |
#endif
|
|
Packit |
1c1d7e |
|