Commit 0dc96d28 authored by Dimitri van Heesch's avatar Dimitri van Heesch

Merge branch 'master' of github.com:doxygen/doxygen

parents b4d5ef17 cd68727a
...@@ -507,7 +507,7 @@ if test "$f_sqlite3" = YES; then ...@@ -507,7 +507,7 @@ if test "$f_sqlite3" = YES; then
printf " Checking for sqlite3 ... " printf " Checking for sqlite3 ... "
if test "$f_sqlite3_path" = NO; then if test "$f_sqlite3_path" = NO; then
sqlite3_hdr_dir="/usr/include /usr/local/include /opt/local/include" sqlite3_hdr_dir="/usr/include /usr/local/include /opt/local/include"
sqlite3_lib_dir="/usr/lib /usr/local/lib /opt/local/lib /usr/lib/x86_64-linux-gnu" sqlite3_lib_dir="/usr/lib /usr/local/lib /opt/local/lib /usr/lib/x86_64-linux-gnu /usr/lib64"
else else
sqlite3_hdr_dir="$f_sqlite3_path/include" sqlite3_hdr_dir="$f_sqlite3_path/include"
sqlite3_lib_dir="$f_sqlite3_path/lib" sqlite3_lib_dir="$f_sqlite3_path/lib"
......
...@@ -2698,6 +2698,8 @@ class Receiver ...@@ -2698,6 +2698,8 @@ class Receiver
<hr> <hr>
\section cmdfcurlyopen \\f{environment}{ \section cmdfcurlyopen \\f{environment}{
\addindex \\f{
Marks the start of a formula that is in a specific environment. Marks the start of a formula that is in a specific environment.
\note The second \c { is optional and is only to help editors (such as \c Vim) to \note The second \c { is optional and is only to help editors (such as \c Vim) to
do proper syntax highlighting by making the number of opening and closing braces do proper syntax highlighting by making the number of opening and closing braces
...@@ -2707,6 +2709,8 @@ class Receiver ...@@ -2707,6 +2709,8 @@ class Receiver
<hr> <hr>
\section cmdfcurlyclose \\f} \section cmdfcurlyclose \\f}
\addindex \\f}
Marks the end of a formula that is in a specific environment. Marks the end of a formula that is in a specific environment.
\sa section \ref cmdfcurlyopen "\\f{" and section \ref formulas "formulas". \sa section \ref cmdfcurlyopen "\\f{" and section \ref formulas "formulas".
...@@ -3032,7 +3036,7 @@ class Receiver ...@@ -3032,7 +3036,7 @@ class Receiver
\section cmdchardot \\. \section cmdchardot \\.
\addindex \\\. \addindex \\\.
This command writes a dot (\c .) to the output. This can be useful to This command writes a dot (`.`) to the output. This can be useful to
prevent ending a brief description when JAVADOC_AUTOBRIEF is enabled prevent ending a brief description when JAVADOC_AUTOBRIEF is enabled
or to prevent starting a numbered list when the dot follows a number at or to prevent starting a numbered list when the dot follows a number at
the start of a line. the start of a line.
...@@ -3040,7 +3044,7 @@ class Receiver ...@@ -3040,7 +3044,7 @@ class Receiver
<hr> <hr>
\section cmddcolon \\:: \section cmddcolon \\::
\addindex \\\:: \addindex \\::
This command writes a double colon (\c \::) to the output. This This command writes a double colon (\c \::) to the output. This
character sequence has to be escaped in some cases, because it is used character sequence has to be escaped in some cases, because it is used
to reference to documented entities. to reference to documented entities.
......
...@@ -381,6 +381,8 @@ ...@@ -381,6 +381,8 @@
} }
\newcommand{\doxyref}[3]{\textbf{#1} (\textnormal{#2}\,\pageref{#3})} \newcommand{\doxyref}[3]{\textbf{#1} (\textnormal{#2}\,\pageref{#3})}
\newcommand{\lcurly}{\{}
\newcommand{\rcurly}{\}}
\newenvironment{DoxyCompactList} \newenvironment{DoxyCompactList}
{\begin{list}{}{ {\begin{list}{}{
\setlength{\leftmargin}{0.5cm} \setlength{\leftmargin}{0.5cm}
......
...@@ -52,6 +52,13 @@ struct CondCtx ...@@ -52,6 +52,13 @@ struct CondCtx
bool skip; bool skip;
}; };
struct CommentCtx
{
CommentCtx(int line)
: lineNr(line) {}
int lineNr;
};
static BufStr * g_inBuf; static BufStr * g_inBuf;
static BufStr * g_outBuf; static BufStr * g_outBuf;
static int g_inBufPos; static int g_inBufPos;
...@@ -64,6 +71,7 @@ static QCString g_fileName; ...@@ -64,6 +71,7 @@ static QCString g_fileName;
static int g_lineNr; static int g_lineNr;
static int g_condCtx; static int g_condCtx;
static QStack<CondCtx> g_condStack; static QStack<CondCtx> g_condStack;
static QStack<CommentCtx> g_commentStack;
static QCString g_blockName; static QCString g_blockName;
static int g_lastCommentContext; static int g_lastCommentContext;
static bool g_inSpecialComment; static bool g_inSpecialComment;
...@@ -256,8 +264,10 @@ void replaceComment(int offset); ...@@ -256,8 +264,10 @@ void replaceComment(int offset);
{ {
g_pythonDocString = TRUE; g_pythonDocString = TRUE;
g_nestingCount=0; g_nestingCount=0;
g_commentStack.clear(); /* to be on the save side */
copyToOutput(yytext,(int)yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(CComment); BEGIN(CComment);
g_commentStack.push(new CommentCtx(g_lineNr));
} }
} }
<Scan>![><!]/.*\n { <Scan>![><!]/.*\n {
...@@ -269,7 +279,9 @@ void replaceComment(int offset); ...@@ -269,7 +279,9 @@ void replaceComment(int offset);
{ {
copyToOutput(yytext,(int)yyleng); copyToOutput(yytext,(int)yyleng);
g_nestingCount=0; g_nestingCount=0;
g_commentStack.clear(); /* to be on the save side */
BEGIN(CComment); BEGIN(CComment);
g_commentStack.push(new CommentCtx(g_lineNr));
} }
} }
<Scan>[Cc\*][><!]/.*\n { <Scan>[Cc\*][><!]/.*\n {
...@@ -284,7 +296,9 @@ void replaceComment(int offset); ...@@ -284,7 +296,9 @@ void replaceComment(int offset);
{ {
copyToOutput(yytext,(int)yyleng); copyToOutput(yytext,(int)yyleng);
g_nestingCount=0; g_nestingCount=0;
g_commentStack.clear(); /* to be on the save side */
BEGIN(CComment); BEGIN(CComment);
g_commentStack.push(new CommentCtx(g_lineNr));
} }
else else
{ {
...@@ -378,8 +392,10 @@ void replaceComment(int offset); ...@@ -378,8 +392,10 @@ void replaceComment(int offset);
<Scan>"/*"[*!]? { /* start of a C comment */ <Scan>"/*"[*!]? { /* start of a C comment */
g_specialComment=(int)yyleng==3; g_specialComment=(int)yyleng==3;
g_nestingCount=0; g_nestingCount=0;
g_commentStack.clear(); /* to be on the save side */
copyToOutput(yytext,(int)yyleng); copyToOutput(yytext,(int)yyleng);
BEGIN(CComment); BEGIN(CComment);
g_commentStack.push(new CommentCtx(g_lineNr));
} }
<Scan>"#"("#")? { <Scan>"#"("#")? {
if (g_lang!=SrcLangExt_Python) if (g_lang!=SrcLangExt_Python)
...@@ -390,7 +406,9 @@ void replaceComment(int offset); ...@@ -390,7 +406,9 @@ void replaceComment(int offset);
{ {
copyToOutput(yytext,(int)yyleng); copyToOutput(yytext,(int)yyleng);
g_nestingCount=0; g_nestingCount=0;
g_commentStack.clear(); /* to be on the save side */
BEGIN(CComment); BEGIN(CComment);
g_commentStack.push(new CommentCtx(g_lineNr));
} }
} }
<Scan>"--!" { <Scan>"--!" {
...@@ -402,7 +420,9 @@ void replaceComment(int offset); ...@@ -402,7 +420,9 @@ void replaceComment(int offset);
{ {
copyToOutput(yytext,(int)yyleng); copyToOutput(yytext,(int)yyleng);
g_nestingCount=0; g_nestingCount=0;
g_commentStack.clear(); /* to be on the save side */
BEGIN(CComment); BEGIN(CComment);
g_commentStack.push(new CommentCtx(g_lineNr));
} }
} }
<Scan>![><!] { <Scan>![><!] {
...@@ -414,7 +434,9 @@ void replaceComment(int offset); ...@@ -414,7 +434,9 @@ void replaceComment(int offset);
{ {
copyToOutput(yytext,(int)yyleng); copyToOutput(yytext,(int)yyleng);
g_nestingCount=0; g_nestingCount=0;
g_commentStack.clear(); /* to be on the save side */
BEGIN(CComment); BEGIN(CComment);
g_commentStack.push(new CommentCtx(g_lineNr));
} }
} }
<CComment>"{@code"/[ \t\n] { <CComment>"{@code"/[ \t\n] {
...@@ -606,6 +628,7 @@ void replaceComment(int offset); ...@@ -606,6 +628,7 @@ void replaceComment(int offset);
} }
<CComment>"/"+"*" { /* nested C comment */ <CComment>"/"+"*" { /* nested C comment */
g_nestingCount++; g_nestingCount++;
g_commentStack.push(new CommentCtx(g_lineNr));
copyToOutput(yytext,(int)yyleng); copyToOutput(yytext,(int)yyleng);
} }
<CComment>"*"+"/" { /* end of C comment */ <CComment>"*"+"/" { /* end of C comment */
...@@ -623,6 +646,7 @@ void replaceComment(int offset); ...@@ -623,6 +646,7 @@ void replaceComment(int offset);
else else
{ {
g_nestingCount--; g_nestingCount--;
CommentCtx *ctx = g_commentStack.pop();
} }
} }
} }
...@@ -951,6 +975,8 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) ...@@ -951,6 +975,8 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName)
g_lineNr = 1; g_lineNr = 1;
g_condStack.clear(); g_condStack.clear();
g_condStack.setAutoDelete(TRUE); g_condStack.setAutoDelete(TRUE);
g_commentStack.clear();
g_commentStack.setAutoDelete(TRUE);
printlex(yy_flex_debug, TRUE, __FILE__, fileName); printlex(yy_flex_debug, TRUE, __FILE__, fileName);
isFixedForm = FALSE; isFixedForm = FALSE;
...@@ -962,7 +988,9 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) ...@@ -962,7 +988,9 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName)
if (g_lang==SrcLangExt_Markdown) if (g_lang==SrcLangExt_Markdown)
{ {
g_nestingCount=0; g_nestingCount=0;
g_commentStack.clear(); /* to be on the save side */
BEGIN(CComment); BEGIN(CComment);
g_commentStack.push(new CommentCtx(g_lineNr));
} }
else else
{ {
...@@ -979,9 +1007,20 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) ...@@ -979,9 +1007,20 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName)
} }
if (g_nestingCount>0 || (YY_START==CComment && g_lang!=SrcLangExt_Markdown)) if (g_nestingCount>0 || (YY_START==CComment && g_lang!=SrcLangExt_Markdown))
{ {
QString tmp= "(probable line reference: ";
bool first = TRUE;
while (!g_commentStack.isEmpty())
{
CommentCtx *ctx = g_commentStack.pop();
if (!first) tmp += ", ";
tmp += QString::number(ctx->lineNr);
first = FALSE;
}
tmp += ")";
warn(g_fileName,g_lineNr,"Reached end of file while still inside a (nested) comment. " warn(g_fileName,g_lineNr,"Reached end of file while still inside a (nested) comment. "
"Nesting level %d",g_nestingCount+1); // add one for "normal" expected end of comment "Nesting level %d %s",g_nestingCount+1,tmp.data()); // add one for "normal" expected end of comment
} }
g_commentStack.clear();
if (Debug::isFlagSet(Debug::CommentCnv)) if (Debug::isFlagSet(Debug::CommentCnv))
{ {
g_outBuf->at(g_outBuf->curPos())='\0'; g_outBuf->at(g_outBuf->curPos())='\0';
......
...@@ -2686,6 +2686,15 @@ EXTRA_PACKAGES=times ...@@ -2686,6 +2686,15 @@ EXTRA_PACKAGES=times
the generated man pages. In case the generated man pages. In case
the manual section does not start with a number, the number 3 is prepended. the manual section does not start with a number, the number 3 is prepended.
The dot (.) at the beginning of the \c MAN_EXTENSION tag is optional. The dot (.) at the beginning of the \c MAN_EXTENSION tag is optional.
]]>
</docs>
</option>
<option type='string' id='MAN_SUBDIR' format='string' defval='' depends='GENERATE_MAN'>
<docs>
<![CDATA[
The \c MAN_SUBDIR tag determines the name of the directory created within \c MAN_OUTPUT
in which the man pages are placed. If defaults to man followed by \c MAN_EXTENSION
with the initial . removed.
]]> ]]>
</docs> </docs>
</option> </option>
......
...@@ -450,6 +450,10 @@ ...@@ -450,6 +450,10 @@
\textbf{#1} (\textnormal{#2}\,\pageref{#3})% \textbf{#1} (\textnormal{#2}\,\pageref{#3})%
} }
% Used by @addindex
\newcommand{\lcurly}{\{}
\newcommand{\rcurly}{\}}
% Used for syntax highlighting % Used for syntax highlighting
\definecolor{comment}{rgb}{0.5,0.0,0.0} \definecolor{comment}{rgb}{0.5,0.0,0.0}
\definecolor{keyword}{rgb}{0.0,0.5,0.0} \definecolor{keyword}{rgb}{0.0,0.5,0.0}
......
...@@ -44,6 +44,9 @@ static QCString escapeLabelName(const char *s) ...@@ -44,6 +44,9 @@ static QCString escapeLabelName(const char *s)
case '%': result+="\\%"; break; case '%': result+="\\%"; break;
case '|': result+="\\texttt{\"|}"; break; case '|': result+="\\texttt{\"|}"; break;
case '!': result+="\"!"; break; case '!': result+="\"!"; break;
case '{': result+="\\lcurly{}"; break;
case '}': result+="\\rcurly{}"; break;
case '~': result+="````~"; break; // to get it a bit better in index together with other special characters
default: result+=c; default: result+=c;
} }
} }
...@@ -79,6 +82,8 @@ QCString LatexDocVisitor::escapeMakeIndexChars(const char *s) ...@@ -79,6 +82,8 @@ QCString LatexDocVisitor::escapeMakeIndexChars(const char *s)
case '|': m_t << "\\texttt{\"|}"; break; case '|': m_t << "\\texttt{\"|}"; break;
case '[': m_t << "["; break; case '[': m_t << "["; break;
case ']': m_t << "]"; break; case ']': m_t << "]"; break;
case '{': m_t << "\\lcurly{}"; break;
case '}': m_t << "\\rcurly{}"; break;
default: str[0]=c; filter(str); break; default: str[0]=c; filter(str); break;
} }
} }
......
...@@ -1375,8 +1375,10 @@ void LatexGenerator::startMemberDoc(const char *clname, ...@@ -1375,8 +1375,10 @@ void LatexGenerator::startMemberDoc(const char *clname,
t << "}"; t << "}";
if (clname) if (clname)
{ {
t << "!" << clname << "@{"; t << "!";
docify(clname); escapeLabelName(clname);
t << "@{";
escapeMakeIndexChars(clname);
t << "}"; t << "}";
} }
t << "}" << endl; t << "}" << endl;
...@@ -2013,13 +2015,18 @@ void LatexGenerator::escapeLabelName(const char *s) ...@@ -2013,13 +2015,18 @@ void LatexGenerator::escapeLabelName(const char *s)
{ {
switch (c) switch (c)
{ {
case '|': t << "\\texttt{\"|}"; break;
case '!': t << "\"!"; break;
case '%': t << "\\%"; break; case '%': t << "\\%"; break;
case '{': t << "\\lcurly{}"; break;
case '}': t << "\\rcurly{}"; break;
case '~': t << "````~"; break; // to get it a bit better in index together with other special characters
// NOTE: adding a case here, means adding it to while below as well! // NOTE: adding a case here, means adding it to while below as well!
default: default:
i=0; i=0;
// collect as long string as possible, before handing it to docify // collect as long string as possible, before handing it to docify
result[i++]=c; result[i++]=c;
while ((c=*p) && c!='%') while ((c=*p) && c!='|' && c!='!' && c!='%' && c!='{' && c!='}' && c!='~')
{ {
result[i++]=c; result[i++]=c;
p++; p++;
...@@ -2042,16 +2049,20 @@ void LatexGenerator::escapeMakeIndexChars(const char *s) ...@@ -2042,16 +2049,20 @@ void LatexGenerator::escapeMakeIndexChars(const char *s)
{ {
switch (c) switch (c)
{ {
case '!': t << "\"!"; break;
case '"': t << "\"\""; break; case '"': t << "\"\""; break;
case '@': t << "\"@"; break; case '@': t << "\"@"; break;
case '|': t << "\\texttt{\"|}"; break;
case '[': t << "["; break; case '[': t << "["; break;
case ']': t << "]"; break; case ']': t << "]"; break;
case '{': t << "\\lcurly{}"; break;
case '}': t << "\\rcurly{}"; break;
// NOTE: adding a case here, means adding it to while below as well! // NOTE: adding a case here, means adding it to while below as well!
default: default:
i=0; i=0;
// collect as long string as possible, before handing it to docify // collect as long string as possible, before handing it to docify
result[i++]=c; result[i++]=c;
while ((c=*p) && c!='"' && c!='@' && c!='[' && c!=']') while ((c=*p) && c!='"' && c!='@' && c!='[' && c!=']' && c!='!' && c!='{' && c!='}' && c!='|')
{ {
result[i++]=c; result[i++]=c;
p++; p++;
......
...@@ -64,9 +64,19 @@ static QCString getExtension() ...@@ -64,9 +64,19 @@ static QCString getExtension()
return ext; return ext;
} }
static QCString getSubdir()
{
QCString dir = Config_getString("MAN_SUBDIR");
if (dir.isEmpty())
{
dir = "man" + getExtension();
}
return dir;
}
ManGenerator::ManGenerator() : OutputGenerator() ManGenerator::ManGenerator() : OutputGenerator()
{ {
dir=Config_getString("MAN_OUTPUT")+"/man" + getExtension(); dir=Config_getString("MAN_OUTPUT") + "/" + getSubdir();
firstCol=TRUE; firstCol=TRUE;
paragraph=TRUE; paragraph=TRUE;
col=0; col=0;
...@@ -106,10 +116,10 @@ void ManGenerator::init() ...@@ -106,10 +116,10 @@ void ManGenerator::init()
err("Could not create output directory %s\n",manOutput.data()); err("Could not create output directory %s\n",manOutput.data());
exit(1); exit(1);
} }
d.setPath(manOutput+"/man"+ext); d.setPath(manOutput + "/" + getSubdir());
if (!d.exists() && !d.mkdir(manOutput+"/man"+ext)) if (!d.exists() && !d.mkdir(manOutput + "/" + getSubdir()))
{ {
err("Could not create output directory %s/man%s\n",manOutput.data(),ext.data()); err("Could not create output directory %s/%s\n",manOutput.data(), getSubdir().data());
exit(1); exit(1);
} }
createSubDirs(d); createSubDirs(d);
...@@ -445,7 +455,7 @@ void ManGenerator::startDoxyAnchor(const char *,const char *manName, ...@@ -445,7 +455,7 @@ void ManGenerator::startDoxyAnchor(const char *,const char *manName,
FTextStream linkstream; FTextStream linkstream;
linkstream.setDevice(&linkfile); linkstream.setDevice(&linkfile);
//linkstream.setEncoding(QTextStream::UnicodeUTF8); //linkstream.setEncoding(QTextStream::UnicodeUTF8);
linkstream << ".so man" << getExtension() << "/" << buildFileName( manName ) << endl; linkstream << ".so " << getSubdir() << "/" << buildFileName( manName ) << endl;
} }
} }
linkfile.close(); linkfile.close();
......
...@@ -77,9 +77,9 @@ const char *i_q_xrefs="INSERT OR REPLACE INTO xrefs " ...@@ -77,9 +77,9 @@ const char *i_q_xrefs="INSERT OR REPLACE INTO xrefs "
static sqlite3_stmt *i_s_xrefs=0; static sqlite3_stmt *i_s_xrefs=0;
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
const char *i_q_memberdef="INSERT OR REPLACE INTO memberdef " const char *i_q_memberdef="INSERT OR REPLACE INTO memberdef "
"( refid, prot, static, const, explicit, inline, final, sealed, new, optional, required, virt, mutable, initonly, readable, writable, gettable, settable, accessor, addable, removable, raisable, name, type, definition, argsstring, scope, initializer, kind, id_bfile, bline, bcolumn, id_file, line, column)" "( refid, prot, static, const, explicit, inline, final, sealed, new, optional, required, virt, mutable, initonly, readable, writable, gettable, settable, accessor, addable, removable, raisable, name, type, definition, argsstring, scope, initializer, kind, id_bodyfile, bodystart, bodyend, id_file, line, column, detaileddescription, briefdescription, inbodydescription)"
"VALUES " "VALUES "
"(:refid,:prot,:static,:const,:explicit,:inline,:final,:sealed,:new,:optional,:required,:virt,:mutable,:initonly,:readable,:writable,:gettable,:settable,:accessor,:addable,:removable,:raisable,:name,:type,:definition,:argsstring,:scope,:initializer,:kind,:id_bfile,:bline,:bcolumn,:id_file,:line,:column)"; "(:refid,:prot,:static,:const,:explicit,:inline,:final,:sealed,:new,:optional,:required,:virt,:mutable,:initonly,:readable,:writable,:gettable,:settable,:accessor,:addable,:removable,:raisable,:name,:type,:definition,:argsstring,:scope,:initializer,:kind,:id_bodyfile,:bodystart,:bodyend,:id_file,:line,:column,:detaileddescription,:briefdescription,:inbodydescription)";
const char *id_q_memberdef="SELECT id FROM memberdef WHERE refid=:refid and id is not null"; const char *id_q_memberdef="SELECT id FROM memberdef WHERE refid=:refid and id is not null";
static sqlite3_stmt *id_s_memberdef=0; static sqlite3_stmt *id_s_memberdef=0;
static sqlite3_stmt *i_s_memberdef=0; static sqlite3_stmt *i_s_memberdef=0;
...@@ -202,12 +202,16 @@ const char * schema_queries[][2] = ...@@ -202,12 +202,16 @@ const char * schema_queries[][2] =
"raisable INTEGER," "raisable INTEGER,"
"kind INTEGER," "kind INTEGER,"
"refid TEXT NOT NULL," "refid TEXT NOT NULL,"
"id_bfile INTEGER," "id_bodyfile INTEGER,"
"bline INTEGER," "bodystart INTEGER,"
"bcolumn INTEGER," "bodyend INTEGER,"
"id_file INTEGER NOT NULL," "id_file INTEGER NOT NULL,"
"line INTEGER NOT NULL," "line INTEGER NOT NULL,"
"column INTEGER NOT NULL)" "column INTEGER NOT NULL,"
"detaileddescription TEXT,"
"briefdescription TEXT,"
"inbodydescription TEXT"
")"
}, },
}; };
...@@ -692,6 +696,12 @@ static void generateSqlite3ForMember(sqlite3*db,MemberDef *md,Definition *def) ...@@ -692,6 +696,12 @@ static void generateSqlite3ForMember(sqlite3*db,MemberDef *md,Definition *def)
bindTextParameter(i_s_memberdef,":scope",md->getScopeString().data(),FALSE); bindTextParameter(i_s_memberdef,":scope",md->getScopeString().data(),FALSE);
} }
// Brief and detail description
bindTextParameter(i_s_memberdef,":briefdescription",md->briefDescription(),FALSE);
bindTextParameter(i_s_memberdef,":detaileddescription",md->documentation(),FALSE);
bindTextParameter(i_s_memberdef,":inbodydescription",md->inbodyDocumentation(),FALSE);
// File location // File location
if (md->getDefLine() != -1) if (md->getDefLine() != -1)
{ {
...@@ -704,18 +714,16 @@ static void generateSqlite3ForMember(sqlite3*db,MemberDef *md,Definition *def) ...@@ -704,18 +714,16 @@ static void generateSqlite3ForMember(sqlite3*db,MemberDef *md,Definition *def)
if (md->getStartBodyLine()!=-1) if (md->getStartBodyLine()!=-1)
{ {
int id_bfile = insertFile(db,md->getBodyDef()->absFilePath()); int id_bodyfile = insertFile(db,md->getBodyDef()->absFilePath());
if (id_bfile == -1) if (id_bodyfile == -1)
{ {
sqlite3_clear_bindings(i_s_memberdef); sqlite3_clear_bindings(i_s_memberdef);
} }
else else
{ {
bindIntParameter(i_s_memberdef,":id_ibfile",id_bfile); bindIntParameter(i_s_memberdef,":id_bodyfile",id_bodyfile);
bindIntParameter(i_s_memberdef,":bline",md->getStartBodyLine()); bindIntParameter(i_s_memberdef,":bodystart",md->getStartBodyLine());
bindIntParameter(i_s_memberdef,":bodyend",md->getEndBodyLine());
// XXX implement getStartBodyColumn
bindIntParameter(i_s_memberdef,":bcolumn",1);
} }
} }
} }
...@@ -837,19 +845,19 @@ static void generateSqlite3ForClass(sqlite3 *db, ClassDef *cd) ...@@ -837,19 +845,19 @@ static void generateSqlite3ForClass(sqlite3 *db, ClassDef *cd)
BaseClassDef *bcd; BaseClassDef *bcd;
for (bcli.toFirst();(bcd=bcli.current());++bcli) for (bcli.toFirst();(bcd=bcli.current());++bcli)
{ {
bindTextParameter(i_s_basecompoundref,":refid",bcd->classDef->getOutputFileBase()); bindTextParameter(i_s_basecompoundref,":refid",bcd->classDef->getOutputFileBase(),FALSE);
bindIntParameter(i_s_basecompoundref,":prot",bcd->prot); bindIntParameter(i_s_basecompoundref,":prot",bcd->prot);
bindIntParameter(i_s_basecompoundref,":virt",bcd->virt); bindIntParameter(i_s_basecompoundref,":virt",bcd->virt);
if (!bcd->templSpecifiers.isEmpty()) if (!bcd->templSpecifiers.isEmpty())
{ {
bindTextParameter(i_s_basecompoundref,":base",insertTemplateSpecifierInScope(bcd->classDef->name(),bcd->templSpecifiers)); bindTextParameter(i_s_basecompoundref,":base",insertTemplateSpecifierInScope(bcd->classDef->name(),bcd->templSpecifiers),FALSE);
} }
else else
{ {
bindTextParameter(i_s_basecompoundref,":base",bcd->classDef->displayName()); bindTextParameter(i_s_basecompoundref,":base",bcd->classDef->displayName(),FALSE);
} }
bindTextParameter(i_s_basecompoundref,":derived",cd->displayName()); bindTextParameter(i_s_basecompoundref,":derived",cd->displayName(),FALSE);
if (-1==step(db,i_s_basecompoundref)) { if (-1==step(db,i_s_basecompoundref)) {
sqlite3_clear_bindings(i_s_basecompoundref); sqlite3_clear_bindings(i_s_basecompoundref);
continue; continue;
......
#! /usr/bin/python
from xml.etree import cElementTree as ET
import os
import sqlite3
import sys
import getopt
# map XML attributes/elements to SQL rows
# --POC: iterate through the children and attributes of the memberdef elelement
# and search it in doxygen_sqlite3.db
g_conn=None
val=[]
def print_unprocessed_attributes(node):
for key in node.attrib:
print "WARNING: '%s' has unprocessed attr '%s'" % (node.tag,key)
def extract_attribute(node,attribute,pnl):
if not attribute in node.attrib:
return
pnl.append("%s = ?" % attribute)
val.append(node.attrib[attribute])
node.attrib.pop(attribute)
def extract_element(node,chld,pnl):
# deal with <tag />
if chld.text == None:
if len(chld.attrib)==0:
node.remove(chld)
return
a=chld.text.strip()
if not a == "":
pnl.append("%s =?" % chld.tag)
val.append(chld.text.strip())
else:
pnl.append("%s IS NULL OR %s = ''" % (chld.tag,chld.tag))
node.remove(chld)
def process_memberdef(node):
q=[]
for chld in node.getchildren():
if chld.tag == "referencedby":
continue
if chld.tag == "references":
continue
if chld.tag == "param":
continue
if chld.tag == "type":
continue
if chld.tag == "location":
extract_attribute(chld,"line",q)
extract_attribute(chld,"column",q)
extract_attribute(chld,"bodystart",q)
extract_attribute(chld,"bodyend",q)
q.append("id_bodyfile=(select id from files where name=?)")
val.append(chld.attrib["bodyfile"])
chld.attrib.pop("bodyfile")
q.append("id_file=(select id from files where name=?)")
val.append(chld.attrib["file"])
chld.attrib.pop("file")
print_unprocessed_attributes(chld)
if len(chld.attrib) == 0:
node.remove(chld)
else:
extract_element(node,chld,q)
for chld in node.getchildren():
print "WARNING: '%s' has unprocessed child elem '%s'" % (node.tag,chld.tag)
extract_attribute(node,"kind",q)
extract_attribute(node,"prot",q)
extract_attribute(node,"static",q)
extract_attribute(node,"mutable",q)
extract_attribute(node,"const",q)
extract_attribute(node,"virt",q)
extract_attribute(node,"explicit",q)
extract_attribute(node,"inline",q)
q.append("refid=?")
val.append(node.attrib['id'])
node.attrib.pop('id')
print_unprocessed_attributes(node)
query="SELECT * FROM memberdef WHERE %s" % " AND ".join(q)
r=[]
try:
r = g_conn.execute(query,val).fetchall()
except sqlite3.OperationalError,e:
print "SQL_ERROR:%s"%e
del val[:]
if not len(r) > 0:
print "TEST_ERROR: Member not found in SQL DB"
def load_xml(name):
context = ET.iterparse(name, events=("start", "end"))
event, root = context.next()
for event, elem in context:
if event == "end" and elem.tag == "memberdef":
process_memberdef(elem)
print "\n== Unprocessed XML =="
# ET.dump(root)
def open_db(dbname):
global g_conn
if dbname == None:
dbname = "doxygen_sqlite3.db"
if not os.path.isfile(dbname):
raise BaseException("No such file %s" % dbname )
g_conn = sqlite3.connect(dbname)
g_conn.execute('PRAGMA temp_store = MEMORY;')
g_conn.row_factory = sqlite3.Row
def main(argv):
try:
opts, args = getopt.getopt(argv, "hd:x:",["help"])
except getopt.GetoptError:
sys.exit(1)
dbname=None
xmlfile=None
for a, o in opts:
if a in ('-h', '--help'):
sys.exit(0)
elif a in ('-d'):
dbname=o
continue
elif a in ('-x'):
xmlfile=o
continue
open_db(dbname)
load_xml(xmlfile)
if __name__ == '__main__':
main(sys.argv[1:])
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment