summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt5
-rw-r--r--README.md4
-rwxr-xr-xaddon/doxypysql/search.py124
-rw-r--r--cmake/FindSQLite3.cmake10
-rw-r--r--doc/autolink.doc2
-rw-r--r--doc/changelog.doc2
-rw-r--r--doc/commands.doc2
-rw-r--r--doc/docblocks.doc19
-rw-r--r--doc/features.doc4
-rw-r--r--doc/install.doc6
-rw-r--r--doc/markdown.doc2
-rw-r--r--doc/searching.doc4
-rw-r--r--doc/starting.doc2
-rw-r--r--examples/jdstyle.cfg2
-rw-r--r--src/classdef.cpp4
-rw-r--r--src/code.l7
-rw-r--r--src/commentscan.h4
-rw-r--r--src/commentscan.l8
-rw-r--r--src/config.h2
-rw-r--r--src/config.xml22
-rw-r--r--src/configimpl.h6
-rw-r--r--src/configimpl.l18
-rw-r--r--src/defargs.l17
-rw-r--r--src/definition.cpp12
-rw-r--r--src/docbookgen.cpp2147
-rw-r--r--src/docbookgen.h2
-rw-r--r--src/docbookvisitor.cpp3
-rw-r--r--src/docparser.cpp237
-rw-r--r--src/docparser.h2
-rw-r--r--src/doctokenizer.h3
-rw-r--r--src/doctokenizer.l31
-rw-r--r--src/dot.cpp2
-rw-r--r--src/doxygen.cpp23
-rw-r--r--src/fortrancode.l17
-rw-r--r--src/fortranscanner.l48
-rw-r--r--src/latexdocvisitor.cpp18
-rw-r--r--src/latexgen.cpp34
-rw-r--r--src/markdown.cpp2
-rw-r--r--src/memberdef.cpp2
-rw-r--r--src/printdocvisitor.h4
-rw-r--r--src/pyscanner.l166
-rw-r--r--src/reflist.cpp24
-rw-r--r--src/rtfdocvisitor.cpp2
-rw-r--r--src/rtfgen.cpp3
-rw-r--r--src/scanner.l30
-rw-r--r--src/sqlite3gen.cpp2158
-rw-r--r--src/tagreader.cpp60
-rw-r--r--src/template.cpp4
-rw-r--r--src/util.cpp29
-rw-r--r--src/util.h5
-rw-r--r--src/vhdlcode.l69
-rw-r--r--src/vhdldocgen.cpp4
-rw-r--r--src/xmldocvisitor.cpp2
-rw-r--r--src/xmlgen.cpp235
-rw-r--r--src/xmlgen.h42
-rw-r--r--testing/009/bug.xml9
-rw-r--r--testing/009/deprecated.xml8
-rw-r--r--testing/009/reminders.xml8
-rw-r--r--testing/009/test.xml8
-rw-r--r--testing/009/todo.xml8
-rw-r--r--testing/012/citelist.xml2
-rw-r--r--testing/README.txt12
-rw-r--r--testing/runtests.py115
63 files changed, 2571 insertions, 3295 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1e0fb55..45c2f2c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -86,7 +86,10 @@ find_package(BISON REQUIRED)
find_package(Threads)
if (sqlite3)
- find_package(SQLite3 REQUIRED)
+ find_package(SQLite3 REQUIRED)
+ if (SQLITE3_VERSION VERSION_LESS 3.9.0)
+ message(SEND_ERROR "Doxygen requires at least sqlite3 version 3.9.0 (installed: ${SQLITE3_VERSION})")
+ endif()
endif()
find_package(Iconv REQUIRED)
diff --git a/README.md b/README.md
index ab3f7fc..3e1c608 100644
--- a/README.md
+++ b/README.md
@@ -36,9 +36,7 @@ Developers
* Doxygen's Doxygen Documentation: <a href="https://codedocs.xyz/doxygen/doxygen/"><img src="https://codedocs.xyz/doxygen/doxygen.svg"/></a>
-* Install
- * Quick install see (./INSTALL)
- * else http://www.doxygen.org/manual/install.html
+* Install: Please read the installation section of the manual (http://www.doxygen.org/manual/install.html)
* Project stats: https://www.openhub.net/p/doxygen
diff --git a/addon/doxypysql/search.py b/addon/doxypysql/search.py
index c185138..5f820de 100755
--- a/addon/doxypysql/search.py
+++ b/addon/doxypysql/search.py
@@ -17,19 +17,19 @@ import json
import re
class MemberType:
- Define="0"
- Function="1"
- Variable="2"
- Typedef="3"
- Enumeration="4"
- EnumValue="5"
- Signal="6"
- Slot="7"
- Friend="8"
- DCOP="9"
- Property="10"
- Event="11"
- File="12"
+ Define="macro definition"
+ Function="function"
+ Variable="variable"
+ Typedef="typedef"
+ Enumeration="enumeration"
+ EnumValue="enumvalue"
+ Signal="signal"
+ Slot="slot"
+ Friend="friend"
+ DCOP="dcop"
+ Property="property"
+ Event="event"
+ File="file"
class RequestType:
References="9901"
@@ -69,27 +69,27 @@ class Finder:
def match(self,row):
if self.row_type is int:
- return " id=?"
+ return " rowid=?"
else:
if g_use_regexp == True:
return " REGEXP (?,%s)" %row
else:
return " %s=?" %row
- def fileName(self,id_file):
- if self.cn.execute("SELECT COUNT(*) FROM files WHERE rowid=?",[id_file]).fetchone()[0] > 1:
- print >>sys.stderr,"WARNING: non-uniq fileid [%s]. Considering only the first match." % id_file
+ def fileName(self,file_id):
+ if self.cn.execute("SELECT COUNT(*) FROM path WHERE rowid=?",[file_id]).fetchone()[0] > 1:
+ sys.stderr.write("WARNING: non-uniq fileid [%s]. Considering only the first match." % file_id)
- for r in self.cn.execute("SELECT * FROM files WHERE rowid=?",[id_file]).fetchall():
+ for r in self.cn.execute("SELECT * FROM path WHERE rowid=?",[file_id]).fetchall():
return r['name']
return ""
def fileId(self,name):
- if self.cn.execute("SELECT COUNT(*) FROM files WHERE"+self.match("name"),[name]).fetchone()[0] > 1:
- print >>sys.stderr,"WARNING: non-uniq file name [%s]. Considering only the first match." % name
+ if self.cn.execute("SELECT COUNT(*) FROM path WHERE"+self.match("name"),[name]).fetchone()[0] > 1:
+ sys.stderr.write("WARNING: non-uniq file name [%s]. Considering only the first match." % name)
- for r in self.cn.execute("SELECT rowid FROM files WHERE"+self.match("name"),[name]).fetchall():
+ for r in self.cn.execute("SELECT rowid FROM path WHERE"+self.match("name"),[name]).fetchall():
return r[0]
return -1
@@ -97,23 +97,24 @@ class Finder:
def references(self):
o=[]
cur = self.cn.cursor()
- cur.execute("SELECT refid FROM memberdef WHERE"+self.match("name"),[self.name])
- refids = cur.fetchall()
+ cur.execute("SELECT rowid FROM memberdef WHERE"+self.match("name"),[self.name])
+ rowids = cur.fetchall()
- if len(refids) == 0:
+ if len(rowids) == 0:
return o
- refid = refids[0]['refid']
+ rowid = rowids[0]['rowid']
cur = self.cn.cursor()
- #TODO:SELECT rowid from refids where refid=refid
- for info in cur.execute("SELECT * FROM xrefs WHERE refid_dst LIKE '%"+refid+"%'"):
+ #TODO:SELECT rowid from refid where refid=refid
+ for info in cur.execute("SELECT * FROM xrefs WHERE dst_rowid=?", [rowid]):
item={}
cur = self.cn.cursor()
- for i2 in cur.execute("SELECT * FROM memberdef WHERE refid=?",[info['src']]):
+ for i2 in cur.execute("SELECT * FROM memberdef WHERE rowid=?",[info['src_rowid']]):
item['name']=i2['name']
- item['src']=info['src']
- item['file']=self.fileName(info['id_file'])
- item['line']=info['line']
+ item['src']=info['src_rowid']
+ # Below no longer directly supported on this entry; can be found from either memberdef
+ #item['file']=self.fileName(info['file_id'])
+ #item['line']=info['line']
o.append(item)
return o
@@ -126,7 +127,7 @@ class Finder:
item['name'] = r['name']
item['definition'] = r['definition']
item['argsstring'] = r['argsstring']
- item['file'] = self.fileName(r['id_file'])
+ item['file'] = self.fileName(r['file_id'])
item['line'] = r['line']
item['detaileddescription'] = r['detaileddescription']
o.append(item)
@@ -134,7 +135,7 @@ class Finder:
###############################################################################
def file(self):
o=[]
- for r in self.cn.execute("SELECT rowid,* FROM files WHERE"+self.match("name"),[self.name]).fetchall():
+ for r in self.cn.execute("SELECT rowid,name FROM local_file WHERE"+self.match("name"),[self.name]).fetchall():
item={}
item['name'] = r['name']
item['id'] = r['rowid']
@@ -151,7 +152,7 @@ class Finder:
if r['argsstring']:
item['argsstring'] = r['argsstring']
item['definition'] = r['initializer']
- item['file'] = self.fileName(r['id_file'])
+ item['file'] = self.fileName(r['file_id'])
item['line'] = r['line']
o.append(item)
return o
@@ -163,7 +164,7 @@ class Finder:
item={}
item['name'] = r['name']
item['definition'] = r['definition']
- item['file'] = self.fileName(r['id_file'])
+ item['file'] = self.fileName(r['file_id'])
item['line'] = r['line']
o.append(item)
return o
@@ -175,16 +176,16 @@ class Finder:
item={}
item['name'] = r['name']
item['definition'] = r['definition']
- item['file'] = self.fileName(r['id_file'])
+ item['file'] = self.fileName(r['file_id'])
item['line'] = r['line']
o.append(item)
return o
###############################################################################
def params(self):
o=[]
- c=self.cn.execute('SELECT id FROM memberdef WHERE'+self.match("name"),[self.name])
+ c=self.cn.execute('SELECT rowid FROM memberdef WHERE'+self.match("name"),[self.name])
for r in c.fetchall():
- #a=("SELECT * FROM params where id=(SELECT id_param FROM memberdef_params where id_memberdef=?",[id_memberdef])
+ #a=("SELECT * FROM param where id=(SELECT param_id FROM memberdef_param where memberdef_id=?",[memberdef_id])
item={}
item['id'] = r['id']
o.append(item)
@@ -202,20 +203,20 @@ class Finder:
def includers(self):
o=[]
fid = self.fileId(self.name)
- c=self.cn.execute('SELECT * FROM includes WHERE id_dst=?',[fid])
+ c=self.cn.execute('SELECT * FROM includes WHERE dst_id=?',[fid])
for r in c.fetchall():
item={}
- item['name'] = self.fileName(r['id_src'])
+ item['name'] = self.fileName(r['src_id'])
o.append(item)
return o
###############################################################################
def includees(self):
o=[]
fid = self.fileId(self.name)
- c=self.cn.execute('SELECT * FROM includes WHERE id_src=?',[fid])
+ c=self.cn.execute('SELECT * FROM includes WHERE src_id=?',[fid])
for r in c.fetchall():
item={}
- item['name'] = self.fileName(r['id_dst'])
+ item['name'] = self.fileName(r['dst_id'])
o.append(item)
return o
###############################################################################
@@ -227,7 +228,7 @@ class Finder:
item['name'] = r['name']
item['definition'] = r['definition']
item['argsstring'] = r['argsstring']
- item['file'] = self.fileName(r['id_file'])
+ item['file'] = self.fileName(r['file_id'])
item['line'] = r['line']
#item['documentation'] = r['documentation']
o.append(item)
@@ -235,19 +236,19 @@ class Finder:
###############################################################################
def baseClasses(self):
o=[]
- c=self.cn.execute('SELECT base FROM basecompoundref WHERE'+self.match("derived"),[self.name])
+ c=self.cn.execute('SELECT compounddef.name FROM compounddef JOIN compoundref ON compounddef.rowid=compoundref.base_rowid WHERE compoundref.derived_rowid IN (SELECT rowid FROM compounddef WHERE'+self.match("name")+')',[self.name])
for r in c.fetchall():
item={}
- item['name'] = r['base']
+ item['name'] = r['name']
o.append(item)
return o
###############################################################################
def subClasses(self):
o=[]
- c=self.cn.execute('SELECT derived FROM basecompoundref WHERE'+self.match("base"),[self.name])
+ c=self.cn.execute('SELECT compounddef.name FROM compounddef JOIN compoundref ON compounddef.rowid=compoundref.derived_rowid WHERE compoundref.base_rowid IN (SELECT rowid FROM compounddef WHERE'+self.match("name")+')',[self.name])
for r in c.fetchall():
item={}
- item['name'] = r['derived']
+ item['name'] = r['name']
o.append(item)
return o
###############################################################################
@@ -268,21 +269,23 @@ def process(f,kind):
}
return request_processors[kind]()
###############################################################################
+
+# the -H option isn't documented. It's one of the more recent additions, but it's treating refids as if they would be a string. I'm just taking a stab at updating it for now, converting to use rowid, and making other edits necessary to get it to run.
def processHref(cn,ref):
j={}
# is it in memberdef ?
table="memberdef"
- if ( cn.execute("SELECT count(*) from %s WHERE refid=?"%table,[ref] ).fetchone()[0] > 0 ):
- for r in cn.execute("SELECT kind,id FROM %s WHERE refid='%s'" % (table,ref) ).fetchall():
- f=Finder(cn,r['id'],int)
+ if ( cn.execute("SELECT count(*) from %s WHERE rowid=?"%table,[ref] ).fetchone()[0] > 0 ):
+ for r in cn.execute("SELECT kind,rowid FROM %s WHERE rowid=?" % table,[ref]).fetchall():
+ f=Finder(cn,r['rowid'],int)
j=process(f,str(r['kind']))
# is it in compounddef ?
table="compounddef"
- if ( cn.execute("SELECT count(*) from %s WHERE refid=?"%table,[ref]).fetchone()[0] > 0 ):
- for r in cn.execute("SELECT id FROM %s WHERE refid=?"%table,[ref] ).fetchall():
- f=Finder(cn,r['id'],int)
+ if ( cn.execute("SELECT count(*) from %s WHERE rowid=?"%table,[ref]).fetchone()[0] > 0 ):
+ for r in cn.execute("SELECT rowid FROM %s WHERE rowid=?"%table,[ref] ).fetchall():
+ f=Finder(cn,r[0],int)
j=process(f,RequestType.Struct)
return j
@@ -290,7 +293,7 @@ def processHref(cn,ref):
def serveCgi():
import cgi
- print 'Content-Type: application/json\n'
+ print('Content-Type: application/json\n')
fieldStorage = cgi.FieldStorage()
form = dict((key, fieldStorage.getvalue(key)) for key in fieldStorage.keys())
@@ -298,17 +301,17 @@ def serveCgi():
if 'href' in form:
ref = form['href']
else:
- print '{"result": null, "error": "no refid given"}'
+ print('{"result": null, "error": "no refid given"}')
sys.exit(0)
cn=openDb('doxygen_sqlite3.db')
j = processHref(cn,ref)
- print json.dumps({"result":j,"error":None})
+ print(json.dumps({"result":j,"error":None}))
###############################################################################
def usage():
- print >>sys.stderr,"""Usage: search.py [Options]
+ sys.stderr.write("""Usage: search.py [Options]
Options:
-h, --help
-d <D> Use database <D> for queries.
@@ -323,7 +326,7 @@ Options:
-M <C> Get all members of class <C>.
-S <C> Get the sub classes of class <C>.
-R Consider the search <term> to be a regex.
-"""
+""")
###############################################################################
def serveCli(argv):
try:
@@ -362,6 +365,8 @@ def serveCli(argv):
elif a in ('-f'):
kind=MemberType.Function
elif a in ('-F'):
+ # undocumented
+ # seems to fit with the lower case "search" patterns?
kind=MemberType.File
elif a in ('-m'):
kind=MemberType.Define
@@ -370,6 +375,7 @@ def serveCli(argv):
elif a in ('-v'):
kind=MemberType.Variable
elif a in ('-H'):
+ # undocumented
ref = o
cn=openDb(dbname)
@@ -378,7 +384,7 @@ def serveCli(argv):
j=processHref(cn,ref)
else:
j=process(f,kind)
- print json.dumps(j,indent=4)
+ print(json.dumps(j,indent=4))
def main(argv):
diff --git a/cmake/FindSQLite3.cmake b/cmake/FindSQLite3.cmake
index 77b8eb4..45cc212 100644
--- a/cmake/FindSQLite3.cmake
+++ b/cmake/FindSQLite3.cmake
@@ -71,8 +71,16 @@ else (SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS)
endif (SQLITE3_INCLUDE_DIRS AND SQLITE3_LIBRARIES)
if (SQLITE3_FOUND)
+
+ # Extract version from header file
+ find_file(SQLITE3_HEADER "sqlite3.h" HINTS ${SQLITE3_INCLUDE_DIRS})
+ if(SQLITE3_HEADER)
+ file(STRINGS "${SQLITE3_HEADER}" _DEF_TMP REGEX "^#define SQLITE_VERSION +\\\"[^\\\"]+\\\"")
+ string (REGEX REPLACE ".*\\\"(([0-9]+[.]?)+).*" "\\1" SQLITE3_VERSION "${_DEF_TMP}")
+ endif (SQLITE3_HEADER)
+
if (NOT Sqlite3_FIND_QUIETLY)
- message(STATUS "Found Sqlite3: ${SQLITE3_LIBRARIES}")
+ message(STATUS "Found Sqlite3: ${SQLITE3_LIBRARIES} (found version \"${SQLITE3_VERSION}\")")
endif (NOT Sqlite3_FIND_QUIETLY)
else (SQLITE3_FOUND)
if (Sqlite3_FIND_REQUIRED)
diff --git a/doc/autolink.doc b/doc/autolink.doc
index ff468e4..bf9fe57 100644
--- a/doc/autolink.doc
+++ b/doc/autolink.doc
@@ -80,7 +80,7 @@
are required to identify the target, i.e. 'func(int) const' and 'func(int)'
target different member functions.
\par Note 3:
- For JavaDoc compatibility a \# may be used instead of a :: in
+ For Javadoc compatibility a \# may be used instead of a :: in
the patterns above.
\par Note 4:
In the documentation of a class containing a member foo,
diff --git a/doc/changelog.doc b/doc/changelog.doc
index 3ba6787..ca00728 100644
--- a/doc/changelog.doc
+++ b/doc/changelog.doc
@@ -2182,7 +2182,7 @@ make sure you add the following:
<h3>New features</h3>
<ul>
<li> Added support for
- <a href="http://daringfireball.net/projects/markdown/">Markdown</a>
+ <a href="https://daringfireball.net/projects/markdown/">Markdown</a>
formatting.
This is enabled by default, but can be disabled by
setting MARKDOWN_SUPPORT to NO. When enabled the following is
diff --git a/doc/commands.doc b/doc/commands.doc
index bb3489a..fb03d98 100644
--- a/doc/commands.doc
+++ b/doc/commands.doc
@@ -3352,7 +3352,7 @@ class Receiver
\addindex \\\@
This command writes an at-sign (\c \@) to the output.
The at-sign has to be escaped in some cases
- because doxygen uses it to detect JavaDoc commands.
+ because doxygen uses it to detect Javadoc commands.
<hr>
\section cmdtilde \\~[LanguageId]
diff --git a/doc/docblocks.doc b/doc/docblocks.doc
index f02e55b..a9cb05a 100644
--- a/doc/docblocks.doc
+++ b/doc/docblocks.doc
@@ -55,7 +55,7 @@ used to provide tooltips at places where an item is referenced.
There are several ways to mark a comment block as a detailed description:
<ol>
-<li> You can use the JavaDoc style, which consist of a C-style comment
+<li> You can use the Javadoc style, which consist of a C-style comment
block starting with two *'s, like this:
\verbatim
@@ -143,7 +143,7 @@ Here is an example:
<li>If \ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" is set to \c YES
in the configuration file,
- then using JavaDoc style comment
+ then using Javadoc style comment
blocks will automatically start a brief description which ends at the
first dot followed by a space or new line. Here is an example:
@@ -299,8 +299,8 @@ sentence of the detailed descriptions
tag to \c NO). Both the brief and the detailed descriptions are optional
for the Qt style.
-By default a JavaDoc style documentation block behaves the same way as a
-Qt style documentation block. This is not according the JavaDoc specification
+By default a Javadoc style documentation block behaves the same way as a
+Qt style documentation block. This is not according the Javadoc specification
however, where the first sentence of the documentation block is automatically
treated as a brief description. To enable this behavior you should set
\ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" to YES in the configuration
@@ -312,7 +312,7 @@ Here is an example:
\endverbatim
Here is the same piece of code as shown above, this time documented using the
-JavaDoc style and \ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" set to YES:
+Javadoc style and \ref cfg_javadoc_autobrief "JAVADOC_AUTOBRIEF" set to YES:
\include jdstyle.cpp
\htmlonly
</p>
@@ -348,7 +348,7 @@ duplication of information. So in practice you should \e avoid the use of
structural commands \e unless other requirements force you to do so.
Structural commands (like \ref cmd_intro "all other commands") start with a backslash
-(<tt>\\</tt>), or an at-sign (<tt>\@</tt>) if you prefer JavaDoc style,
+(<tt>\\</tt>), or an at-sign (<tt>\@</tt>) if you prefer Javadoc style,
followed by a command name and one or more parameters.
For instance, if you want to document the class \c Test in the example
above, you could have also put the following documentation block somewhere
@@ -632,7 +632,7 @@ and is ideal for a short description.
For longer descriptions you often will find the
need for some more structure, like a block of verbatim text, a list, or a
simple table. For this doxygen supports the
-<a href="http://daringfireball.net/projects/markdown/syntax">Markdown</a>
+<a href="https://daringfireball.net/projects/markdown/syntax">Markdown</a>
syntax, including parts of the
<a href="https://michelf.ca/projects/php-markdown/extra/">Markdown Extra</a>
extension.
@@ -648,8 +648,9 @@ forms of additional markup on top of Markdown formatting.
1. <a href="https://en.wikipedia.org/wiki/Javadoc">Javadoc</a> like markup.
See \ref commands for a complete overview of all commands supported by doxygen.
-2. <a href="https://en.wikipedia.org/wiki/C_Sharp_(programming_language)#XML_documentation_system">XML</a> markup
- as specified in the C# standard. See \ref xmlcmds for the XML commands supported by doxygen.
+2. <a href="https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/xmldoc/recommended-tags-for-documentation-comments">XML</a> markup
+ as specified in the <a href="http://standards.iso.org/ittf/PubliclyAvailableStandards/c042926_ISO_IEC_23270_2006(E).zip">C# standard</a>.
+ See \ref xmlcmds for the XML commands supported by doxygen.
If this is still not enough doxygen also supports a \ref htmlcmds "subset" of
the <a href="https://en.wikipedia.org/wiki/HTML">HTML</a> markup language.
diff --git a/doc/features.doc b/doc/features.doc
index f6aa7c1..8b19898 100644
--- a/doc/features.doc
+++ b/doc/features.doc
@@ -33,7 +33,7 @@
<li>Supports documentation of files, namespaces, packages, classes,
structs, unions, templates, variables, functions, typedefs, enums and
defines.
-<li>JavaDoc (1.1), qdoc3 (partially), and ECMA-334 (C# spec.) compatible.
+<li>Javadoc (1.1), qdoc3 (partially), and ECMA-334 (C# spec.) compatible.
<li>Comes with a GUI frontend (Doxywizard) to ease editing the options and
run doxygen. The GUI is available on Windows, Linux, and MacOSX.
<li>Automatically generates class and collaboration diagrams in HTML (as clickable
@@ -100,7 +100,7 @@
Although doxygen can now be used in any project written in a language that is
supported by doxygen, initially it was specifically designed to be used for projects
that make use of Qt Software's
-<A HREF="http://qt-project.org/">Qt toolkit</A>. I have tried to
+<A HREF="https://www.qt.io/developers/">Qt toolkit</A>. I have tried to
make doxygen `Qt-compatible'. That is: Doxygen can read the documentation contained in
the Qt source code and create a class browser that looks quite similar to the
one that is generated by Qt Software. Doxygen understands the C++ extensions
diff --git a/doc/install.doc b/doc/install.doc
index 7df0dee..d64b259 100644
--- a/doc/install.doc
+++ b/doc/install.doc
@@ -47,7 +47,7 @@ tools should be installed.
<ul>
<li>Qt Software's GUI toolkit
- <a href="http://qt-project.org/">Qt</A>
+ <a href="https://www.qt.io/developers/">Qt</A>
\addindex Qt
version 4.3 or higher (including Qt 5).
This is needed to build the GUI front-end doxywizard.
@@ -211,12 +211,12 @@ If you want to produce compressed HTML files (see \ref
cfg_generate_htmlhelp "GENERATE_HTMLHELP") in the configuration file, then
you need the Microsoft HTML help workshop.
You can download it from
-<a href="http://www.microsoft.com/en-us/download/details.aspx?id=21138">Microsoft</a>.
+<a href="https://www.microsoft.com/en-us/download/details.aspx?id=21138">Microsoft</a>.
If you want to produce Qt Compressed Help files (see \ref
cfg_qhg_location "QHG_LOCATION") in the configuration file, then
you need qhelpgenerator which is part of Qt.
-You can download Qt from <a href="http://qt-project.org/downloads">Qt Software Downloads</a>.
+You can download Qt from <a href="https://www.qt.io/download">Qt Software Downloads</a>.
In order to generate PDF output or use scientific formulas you will also need to
install <a href="https://en.wikipedia.org/wiki/LaTeX">LaTeX</a> and
diff --git a/doc/markdown.doc b/doc/markdown.doc
index eebcb40..5edbaf9 100644
--- a/doc/markdown.doc
+++ b/doc/markdown.doc
@@ -41,7 +41,7 @@ the extensions that doxygen supports.
Finally section \ref markdown_dox discusses some specifics for doxygen's
implementation of the Markdown standard.
-[markdown]: http://daringfireball.net/projects/markdown/
+[markdown]: https://daringfireball.net/projects/markdown/
[mdextra]: https://michelf.ca/projects/php-markdown/extra/
[github]: https://github.github.com/github-flavored-markdown/
diff --git a/doc/searching.doc b/doc/searching.doc
index cb6b84a..9bc518a 100644
--- a/doc/searching.doc
+++ b/doc/searching.doc
@@ -126,7 +126,7 @@ has its own advantages and disadvantages:
options you may want to set. After doxygen has finished you will find
a Makefile in the HTML output directory. Running "make install" on this
Makefile will compile and install the doc set.
- See <a href="https://developer.apple.com/library/mac/#featuredarticles/DoxygenXcode/_index.html">this
+ See <a href="https://developer.apple.com/library/archive/featuredarticles/DoxygenXcode/_index.html">this
article</a> for more info.
Advantage of this method is that it nicely integrates with the Xcode
@@ -139,7 +139,7 @@ has its own advantages and disadvantages:
<h2>6. Qt Compressed Help</h2>
If you develop for or want to install the Qt application framework,
you will get an application
- called <a href="http://qt-project.org/doc/qt-4.8/assistant-manual.html">Qt assistant</a>.
+ called <a href="http://doc.qt.io/archives/qt-4.8/assistant-manual.html">Qt assistant</a>.
This is a help viewer for Qt Compressed Help files (<code>.qch</code>).
To enable this feature set \ref cfg_generate_qhp "GENERATE_QHP" to \c YES.
diff --git a/doc/starting.doc b/doc/starting.doc
index 0765a3b..64d3be0 100644
--- a/doc/starting.doc
+++ b/doc/starting.doc
@@ -263,7 +263,7 @@ capabilities of the man page format, so some information
\subsection docbook_out DocBook output
\addindex docbook
Doxygen can also generate output in the
-<a href="http://docbook.org/">DocBook</a> format. How to process the
+<a href="https://docbook.org/">DocBook</a> format. How to process the
DocBook output is beyond the scope of this manual.
\section step3 Step 3: Documenting the sources
diff --git a/examples/jdstyle.cfg b/examples/jdstyle.cfg
index 0ddc0d9..d94089d 100644
--- a/examples/jdstyle.cfg
+++ b/examples/jdstyle.cfg
@@ -1,4 +1,4 @@
-PROJECT_NAME = "JavaDoc Style"
+PROJECT_NAME = "Javadoc Style"
OUTPUT_DIRECTORY = ../html/examples/jdstyle
GENERATE_LATEX = YES
GENERATE_MAN = NO
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 787cd5e..28308db 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -671,6 +671,10 @@ void ClassDef::internalInsertMember(MemberDef *md,
case MemberType_Variable:
addMemberToList(MemberListType_variableMembers,md,FALSE);
break;
+ case MemberType_Define:
+ warn(md->getDefFileName(),md->getDefLine()-1,"A define (%s) cannot be made a member of %s",
+ md->name().data(), this->name().data());
+ break;
default:
err("Unexpected member type %d found!\n",md->memberType());
}
diff --git a/src/code.l b/src/code.l
index bb9744b..e6dd8ba 100644
--- a/src/code.l
+++ b/src/code.l
@@ -2172,8 +2172,12 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
g_code->codify(yytext);
endFontClass();
}
+<ClassName>{ID}("."{ID})* |
<ClassName>{ID}("::"{ID})* {
- g_curClassName=yytext;
+ if(g_insideCS)
+ g_curClassName=substitute(yytext,".","::");
+ else
+ g_curClassName=yytext;
addType();
if (g_curClassName=="alignas")
{
@@ -2629,6 +2633,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
addType();
g_name=varname;
}
+<Body>{SCOPETNAME}{B}*"<"[^\n\/\-\.\{\"\>]*">"/{BN}*"(" |
<Body>{SCOPETNAME}/{BN}*"(" { // a() or c::a() or t<A,B>::a() or A\B\foo()
addType();
generateFunctionLink(*g_code,yytext);
diff --git a/src/commentscan.h b/src/commentscan.h
index e202f0a..d324969 100644
--- a/src/commentscan.h
+++ b/src/commentscan.h
@@ -40,7 +40,7 @@ class ParserInterface;
* @param[in,out] lineNr The line number at which the comment block was found.
* When the function returns it will be set to the last line parsed.
* @param[in] isBrief TRUE iff this comment block represents a brief description.
- * @param[in] isJavaDocStyle TRUE iff this comment block is in "JavaDoc" style.
+ * @param[in] isJavadocStyle TRUE iff this comment block is in "Javadoc" style.
* This means that it starts as a brief description until the end of
* the sentences is found and then proceeds as a detailed description.
* @param[in] isInbody TRUE iff this comment block is located in the body of
@@ -65,7 +65,7 @@ bool parseCommentBlock(ParserInterface *parser,
const QCString &fileName,
int &lineNr,
bool isBrief,
- bool isJavaDocStyle,
+ bool isJavadocStyle,
bool isInbody,
Protection &prot,
int &position,
diff --git a/src/commentscan.l b/src/commentscan.l
index c3639b5..e317a86 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -1597,8 +1597,12 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
<PageDocArg1>. { // ignore other stuff
}
<PageDocArg2>.*"\n" { // second argument; page title
- yyLineNr++;
- current->args = yytext;
+ yyLineNr++;
+ // bug 748927
+ QCString tmp = yytext;
+ tmp = substitute(substitute(tmp,"@<","&lt;"),"@>","&gt;");
+ tmp = substitute(substitute(tmp,"\\<","&lt;"),"\\>","&gt;");
+ current->args = tmp;
addOutput('\n');
BEGIN( Comment );
}
diff --git a/src/config.h b/src/config.h
index 98f5a92..102774e 100644
--- a/src/config.h
+++ b/src/config.h
@@ -66,7 +66,7 @@ namespace Config
* and replaces environment variables.
* \param clearHeaderAndFooter set to TRUE when writing header and footer templates.
*/
- void postProcess(bool clearHeaderAndFooter);
+ void postProcess(bool clearHeaderAndFooter, bool compare = FALSE);
/*! Check the validity of the parsed options and correct or warn the user where needed. */
void checkAndCorrect();
diff --git a/src/config.xml b/src/config.xml
index 08795dc..0c09cca 100644
--- a/src/config.xml
+++ b/src/config.xml
@@ -650,7 +650,7 @@ Go to the <a href="commands.html">next</a> section or return to the
<![CDATA[
If the \c MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all
comments according to the Markdown format, which allows for more readable
- documentation. See http://daringfireball.net/projects/markdown/ for details.
+ documentation. See https://daringfireball.net/projects/markdown/ for details.
The output of markdown processing is further processed by doxygen, so you
can mix doxygen, HTML, and XML commands with Markdown formatting.
Disable only in case of backward compatibilities issues.
@@ -2039,15 +2039,15 @@ hr.footer {
<![CDATA[
If the \c GENERATE_DOCSET tag is set to \c YES, additional index files
will be generated that can be used as input for
- <a href="https://developer.apple.com/tools/xcode/">Apple's Xcode 3
+ <a href="https://developer.apple.com/xcode/">Apple's Xcode 3
integrated development environment</a>, introduced with OSX 10.5 (Leopard).
To create a documentation set, doxygen will generate a Makefile in the
HTML output directory. Running \c make will produce the docset in that
directory and running <code>make install</code> will install the docset in
<code>~/Library/Developer/Shared/Documentation/DocSets</code>
so that Xcode will find it at startup. See
- https://developer.apple.com/tools/creatingdocsetswithdoxygen.html for
- more information.
+ https://developer.apple.com/library/archive/featuredarticles/DoxygenXcode/_index.html
+ for more information.
]]>
</docs>
</option>
@@ -2095,7 +2095,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
doxygen generates three additional HTML index files:
\c index.hhp, \c index.hhc, and \c index.hhk. The \c index.hhp is a
project file that can be read by
- <a href="http://www.microsoft.com/en-us/download/details.aspx?id=21138">
+ <a href="https://www.microsoft.com/en-us/download/details.aspx?id=21138">
Microsoft's HTML Help Workshop</a>
on Windows.
<br>
@@ -2191,7 +2191,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
<![CDATA[
The \c QHP_NAMESPACE tag specifies the namespace to use when generating
Qt Help Project output. For more information please see
- <a href="http://doc.qt.io/qt-4.8/qthelpproject.html#namespace">Qt Help Project / Namespace</a>.
+ <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace">Qt Help Project / Namespace</a>.
]]>
</docs>
</option>
@@ -2200,7 +2200,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
<![CDATA[
The \c QHP_VIRTUAL_FOLDER tag specifies the namespace to use when
generating Qt Help Project output. For more information please see
- <a href="http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>.
+ <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders">Qt Help Project / Virtual Folders</a>.
]]>
</docs>
</option>
@@ -2208,7 +2208,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
<docs>
<![CDATA[
If the \c QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom filter to add. For more information please see
- <a href="http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+ <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
]]>
</docs>
</option>
@@ -2217,7 +2217,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
<![CDATA[
The \c QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the custom filter to add.
For more information please see
- <a href="http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+ <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
]]>
</docs>
</option>
@@ -2225,7 +2225,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
<docs>
<![CDATA[
The \c QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's filter section matches.
- <a href="http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+ <a href="http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
]]>
</docs>
</option>
@@ -2375,7 +2375,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
<value name="NativeMML" desc="(i.e. MathML)"/>
<value name="SVG"/>
</option>
- <option type='string' id='MATHJAX_RELPATH' format='string' defval='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/' depends='USE_MATHJAX'>
+ <option type='string' id='MATHJAX_RELPATH' format='string' defval='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/' depends='USE_MATHJAX'>
<docs>
<![CDATA[
When MathJax is enabled you need to specify the location relative to the
diff --git a/src/configimpl.h b/src/configimpl.h
index ef8bb21..1594d47 100644
--- a/src/configimpl.h
+++ b/src/configimpl.h
@@ -75,6 +75,7 @@ class ConfigOption
virtual void writeTemplate(FTextStream &t,bool sl,bool upd) = 0;
virtual void compareDoxyfile(FTextStream &t) = 0;
virtual void convertStrToVal() {}
+ virtual void emptyValueToDefault() {}
virtual void substEnvVars() = 0;
virtual void init() {}
@@ -189,6 +190,7 @@ class ConfigString : public ConfigOption
void compareDoxyfile(FTextStream &t);
void substEnvVars();
void init() { m_value = m_defValue.copy(); }
+ void emptyValueToDefault() { if(m_value.isEmpty()) m_value=m_defValue; };
private:
QCString m_value;
@@ -491,6 +493,10 @@ class ConfigImpl
*/
void convertStrToVal();
+ /*! Sets default value in case value is empty
+ */
+ void emptyValueToDefault();
+
/*! Replaces references to environment variable by the actual value
* of the environment variable.
*/
diff --git a/src/configimpl.l b/src/configimpl.l
index 3fb1360..ed5b052 100644
--- a/src/configimpl.l
+++ b/src/configimpl.l
@@ -868,7 +868,7 @@ static void readIncludeFile(const char *incName)
}
BEGIN(Start);
}
-<GetStrList>[ \t]+ {
+<GetStrList>[ \t,]+ {
if (!elemStr.isEmpty())
{
//printf("elemStr2=`%s'\n",elemStr.data());
@@ -922,7 +922,7 @@ static void readIncludeFile(const char *incName)
bs.data(),yyLineNr,yyFileName.data());
}
}
-<GetStrList>[^ \#\"\t\r\n]+ {
+<GetStrList>[^ \#\"\t\r\n,]+ {
elemStr+=configStringRecode(yytext,encoding,"UTF-8");
}
<SkipComment>\n { yyLineNr++; BEGIN(Start); }
@@ -983,6 +983,15 @@ void ConfigImpl::convertStrToVal()
option->convertStrToVal();
}
}
+void ConfigImpl::emptyValueToDefault()
+{
+ QListIterator<ConfigOption> it = iterator();
+ ConfigOption *option;
+ for (;(option=it.current());++it)
+ {
+ option->emptyValueToDefault();
+ }
+}
static void substEnvVarsInString(QCString &s)
{
@@ -1854,7 +1863,7 @@ void Config::writeTemplate(FTextStream &t,bool shortList,bool update)
void Config::compareDoxyfile(FTextStream &t)
{
- postProcess(FALSE);
+ postProcess(FALSE, TRUE);
ConfigImpl::instance()->compareDoxyfile(t);
}
@@ -1863,9 +1872,10 @@ bool Config::parse(const char *fileName,bool update)
return ConfigImpl::instance()->parse(fileName,update);
}
-void Config::postProcess(bool clearHeaderAndFooter)
+void Config::postProcess(bool clearHeaderAndFooter, bool compare)
{
ConfigImpl::instance()->substituteEnvironmentVars();
+ if (!compare)ConfigImpl::instance()->emptyValueToDefault();
ConfigImpl::instance()->convertStrToVal();
// avoid bootstrapping issues when the config file already
diff --git a/src/defargs.l b/src/defargs.l
index 7f1e1bb..52052fa 100644
--- a/src/defargs.l
+++ b/src/defargs.l
@@ -52,6 +52,7 @@
#include <assert.h>
#include <ctype.h>
#include <qregexp.h>
+#include <qcstringlist.h>
#include "defargs.h"
#include "entry.h"
@@ -102,6 +103,19 @@ static int yyread(char *buf,int max_size)
return c;
}
+/* bug_520975 */
+static bool checkSpecialType(QCString &typ, QCString &nam)
+{
+ if (nam == "unsigned" || nam == "signed" ||
+ nam == "volatile" || nam == "const") return TRUE;
+ QCStringList qsl=QCStringList::split(' ',typ);
+ for (uint j=0;j<qsl.count();j++)
+ {
+ if (!(qsl[j] == "unsigned" || qsl[j] == "signed" ||
+ qsl[j] == "volatile" || qsl[j] == "const")) return FALSE;
+ }
+ return TRUE;
+}
%}
B [ \t]
@@ -384,8 +398,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
a->type.mid(sv)=="union" ||
a->type.mid(sv)=="class" ||
a->type.mid(sv)=="typename" ||
- a->type=="const" ||
- a->type=="volatile"
+ checkSpecialType(a->type, a->name)
)
{
a->type = a->type + " " + a->name;
diff --git a/src/definition.cpp b/src/definition.cpp
index 33cf7ea..936565d 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -1638,13 +1638,21 @@ void Definition::mergeRefItems(Definition *d)
m_impl->xrefListItems->setAutoDelete(TRUE);
}
QListIterator<ListItemInfo> slii(*xrefList);
+ QListIterator<ListItemInfo> mlii(*m_impl->xrefListItems);
ListItemInfo *lii;
+ ListItemInfo *mii;
for (slii.toFirst();(lii=slii.current());++slii)
{
- if (_getXRefListId(lii->type)==-1)
+ bool found = false;
+ for (mlii.toFirst();(mii=mlii.current());++mlii)
{
- m_impl->xrefListItems->append(new ListItemInfo(*lii));
+ if ((qstrcmp(lii->type,mii->type)==0) && (lii->itemId == mii->itemId))
+ {
+ found = true;
+ break;
+ }
}
+ if (!found) m_impl->xrefListItems->append(new ListItemInfo(*lii));
}
}
}
diff --git a/src/docbookgen.cpp b/src/docbookgen.cpp
index bfec8bf..8c8ed90 100644
--- a/src/docbookgen.cpp
+++ b/src/docbookgen.cpp
@@ -70,52 +70,6 @@
#endif
//------------------
-class DocbookSectionMapper : public QIntDict<char>
-{
- public:
- DocbookSectionMapper() : QIntDict<char>(47)
- {
- insert(MemberListType_pubTypes,"public-type");
- insert(MemberListType_pubMethods,"public-func");
- insert(MemberListType_pubAttribs,"public-attrib");
- insert(MemberListType_pubSlots,"public-slot");
- insert(MemberListType_signals,"signal");
- insert(MemberListType_dcopMethods,"dcop-func");
- insert(MemberListType_properties,"property");
- insert(MemberListType_events,"event");
- insert(MemberListType_pubStaticMethods,"public-static-func");
- insert(MemberListType_pubStaticAttribs,"public-static-attrib");
- insert(MemberListType_proTypes,"protected-type");
- insert(MemberListType_proMethods,"protected-func");
- insert(MemberListType_proAttribs,"protected-attrib");
- insert(MemberListType_proSlots,"protected-slot");
- insert(MemberListType_proStaticMethods,"protected-static-func");
- insert(MemberListType_proStaticAttribs,"protected-static-attrib");
- insert(MemberListType_pacTypes,"package-type");
- insert(MemberListType_pacMethods,"package-func");
- insert(MemberListType_pacAttribs,"package-attrib");
- insert(MemberListType_pacStaticMethods,"package-static-func");
- insert(MemberListType_pacStaticAttribs,"package-static-attrib");
- insert(MemberListType_priTypes,"private-type");
- insert(MemberListType_priMethods,"private-func");
- insert(MemberListType_priAttribs,"private-attrib");
- insert(MemberListType_priSlots,"private-slot");
- insert(MemberListType_priStaticMethods,"private-static-func");
- insert(MemberListType_priStaticAttribs,"private-static-attrib");
- insert(MemberListType_friends,"friend");
- insert(MemberListType_related,"related");
- insert(MemberListType_decDefineMembers,"define");
- insert(MemberListType_decProtoMembers,"prototype");
- insert(MemberListType_decTypedefMembers,"typedef");
- insert(MemberListType_decEnumMembers,"enum");
- insert(MemberListType_decFuncMembers,"func");
- insert(MemberListType_decVarMembers,"var");
- }
-};
-
-static DocbookSectionMapper g_docbookSectionMapper;
-
-
inline void writeDocbookString(FTextStream &t,const char *s)
{
t << convertToDocBook(s);
@@ -149,20 +103,6 @@ inline void writeDocbookCodeString(FTextStream &t,const char *s, int &col)
}
}
-static void writeDocbookHeaderMainpage(FTextStream &t, QCString &pageName)
-{
- t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
- t << "<chapter xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"";
- if (!pageName.isEmpty()) t << " xml:id=\"_" << pageName << "\"";
- t << ">" << endl;
-}
-
-static void writeDocbookHeader_ID(FTextStream &t, QCString id)
-{
- t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
- t << "<section xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:id=\"_" << id << "\">" << endl;
-}
-
static void addIndexTerm(FTextStream &t, QCString prim, QCString sec = "")
{
t << "<indexterm><primary>";
@@ -187,25 +127,6 @@ void writeDocbookLink(FTextStream &t,const char * /*extRef*/,const char *compoun
t << "</link>";
}
-class TextGeneratorDocbookImpl : public TextGeneratorIntf
-{
- public:
- TextGeneratorDocbookImpl(FTextStream &t): m_t(t) {}
- void writeString(const char *s,bool /*keepSpaces*/) const
- {
- writeDocbookString(m_t,s);
- }
- void writeBreak(int) const {}
- void writeLink(const char *extRef,const char *file,
- const char *anchor,const char *text
- ) const
- {
- writeDocbookLink(m_t,extRef,file,anchor,text,0);
- }
- private:
- FTextStream &m_t;
-};
-
DocbookCodeGenerator::DocbookCodeGenerator(FTextStream &t) : m_lineNumber(-1), m_col(0),
m_insideCodeLine(FALSE), m_insideSpecialHL(FALSE)
{
@@ -328,2074 +249,6 @@ void DocbookCodeGenerator::endCodeFragment()
m_t << "</computeroutput></literallayout>" << endl;
}
-static void writeTemplateArgumentList(ArgumentList *al,
- FTextStream &t,
- Definition *scope,
- FileDef *fileScope,
- int indent)
-{
- QCString indentStr;
- indentStr.fill(' ',indent);
- if (al)
- {
- t << indentStr << "<templateparamlist>" << endl;
- ArgumentListIterator ali(*al);
- Argument *a;
- for (ali.toFirst();(a=ali.current());++ali)
- {
- t << indentStr << " <param>" << endl;
- if (!a->type.isEmpty())
- {
- t << indentStr << " <type>";
- linkifyText(TextGeneratorDocbookImpl(t),scope,fileScope,0,a->type);
- t << "</type>" << endl;
- }
- if (!a->name.isEmpty())
- {
- t << indentStr << " <declname>" << a->name << "</declname>" << endl;
- t << indentStr << " <defname>" << a->name << "</defname>" << endl;
- }
- if (!a->defval.isEmpty())
- {
- t << indentStr << " <defval>";
- linkifyText(TextGeneratorDocbookImpl(t),scope,fileScope,0,a->defval);
- t << "</defval>" << endl;
- }
- t << indentStr << " </param>" << endl;
- }
- t << indentStr << "</templateparamlist>" << endl;
- }
-}
-
-static void writeTemplateList(ClassDef *cd,FTextStream &t)
-{
- writeTemplateArgumentList(cd->templateArguments(),t,cd,0,4);
-}
-
-static void writeDocbookDocBlock(FTextStream &t,
- const QCString &fileName,
- int lineNr,
- Definition *scope,
- MemberDef * md,
- const QCString &text)
-{
- QCString stext = text.stripWhiteSpace();
- if (stext.isEmpty()) return;
- // convert the documentation string into an abstract syntax tree
- DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,text,FALSE,FALSE);
- // create a code generator
- DocbookCodeGenerator *docbookCodeGen = new DocbookCodeGenerator(t);
- // create a parse tree visitor for Docbook
- DocbookDocVisitor *visitor = new DocbookDocVisitor(t,*docbookCodeGen);
- // visit all nodes
- root->accept(visitor);
- // clean up
- delete visitor;
- delete docbookCodeGen;
- delete root;
-}
-
-void writeDocbookCodeBlock(FTextStream &t,FileDef *fd)
-{
- ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension());
- SrcLangExt langExt = getLanguageFromFileName(fd->getDefFileExtension());
- pIntf->resetCodeParserState();
- DocbookCodeGenerator *docbookGen = new DocbookCodeGenerator(t);
- pIntf->parseCode(*docbookGen, // codeOutIntf
- 0, // scopeName
- fileToString(fd->absFilePath(),Config_getBool(FILTER_SOURCE_FILES)),
- langExt, // lang
- FALSE, // isExampleBlock
- 0, // exampleName
- fd, // fileDef
- -1, // startLine
- -1, // endLine
- FALSE, // inlineFragement
- 0, // memberDef
- TRUE // showLineNumbers
- );
- docbookGen->finish();
- delete docbookGen;
-}
-
-static QCString classOutputFileBase(ClassDef *cd)
-{
- //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
- //if (inlineGroupedClasses && cd->partOfGroups()!=0)
- return cd->getOutputFileBase();
- //else
- // return cd->getOutputFileBase();
-}
-
-static QCString memberOutputFileBase(MemberDef *md)
-{
- //static bool inlineGroupedClasses = Config_getBool(INLINE_GROUPED_CLASSES);
- //if (inlineGroupedClasses && md->getClassDef() && md->getClassDef()->partOfGroups()!=0)
- // return md->getClassDef()->getDocbookOutputFileBase();
- //else
- // return md->getOutputFileBase();
- return md->getOutputFileBase();
-}
-
-static void generateTOC(FTextStream &t, PageDef *pd)
-{
- if (pd->localToc().isDocbookEnabled())
- {
- t << " <toc>" << endl;
- t << " <title>" << theTranslator->trRTFTableOfContents() << "</title>" << endl;
- SectionDict *sectionDict = pd->getSectionDict();
- SDict<SectionInfo>::Iterator li(*sectionDict);
- SectionInfo *si;
- int level=1,l;
- bool inLi[5]={ FALSE, FALSE, FALSE, FALSE, FALSE };
- int maxLevel = pd->localToc().docbookLevel();
- for (li.toFirst();(si=li.current());++li)
- {
- if (si->type==SectionInfo::Section ||
- si->type==SectionInfo::Subsection ||
- si->type==SectionInfo::Subsubsection ||
- si->type==SectionInfo::Paragraph)
- {
- //printf(" level=%d title=%s\n",level,si->title.data());
- int nextLevel = (int)si->type;
- if (nextLevel>level)
- {
- for (l=level;l<nextLevel;l++)
- {
- if (l < maxLevel) t << " <tocdiv>" << endl;
- }
- }
- else if (nextLevel<level)
- {
- for (l=level;l>nextLevel;l--)
- {
- inLi[l]=FALSE;
- if (l <= maxLevel) t << " </tocdiv>" << endl;
- }
- }
- if (nextLevel <= maxLevel)
- {
- QCString titleDoc = convertToDocBook(si->title);
- t << " <tocentry>" << (si->title.isEmpty()?si->label:titleDoc) << "</tocentry>" << endl;
- }
- inLi[nextLevel]=TRUE;
- level = nextLevel;
- }
- }
- t << " </toc>" << endl;
- }
-}
-
-static void generateSourceRefList(FTextStream &t,const char *scopeName, const QCString &text,MemberSDict *members, Definition *def)
-{
- static bool sourceBrowser = Config_getBool(SOURCE_BROWSER);
- static bool refLinkSource = Config_getBool(REFERENCES_LINK_SOURCE);
-
- if (members)
- {
- members->sort();
-
- t << "<formalpara><title>" << convertToDocBook(text) << "</title><para>";
-
- QCString ldefLine=theTranslator->trWriteList(members->count());
-
- QRegExp marker("@[0-9]+");
- int index=0,newIndex,matchLen;
- // now replace all markers in inheritLine with links to the classes
- while ((newIndex=marker.match(ldefLine,index,&matchLen))!=-1)
- {
- bool ok;
- t << convertToDocBook(ldefLine.mid(index,newIndex-index));
- uint entryIndex = ldefLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
- MemberDef *md=members->at(entryIndex);
- if (ok && md)
- {
- QCString scope=md->getScopeString();
- QCString name=md->name();
- //printf("class=%p scope=%s scopeName=%s\n",md->getClassDef(),scope.data(),scopeName);
- if (!scope.isEmpty() && scope!=scopeName)
- {
- name.prepend(scope+getLanguageSpecificSeparator(def->getLanguage()));
- }
- if (!md->isObjCMethod() &&
- (md->isFunction() || md->isSlot() ||
- md->isPrototype() || md->isSignal()
- )
- )
- {
- name+="()";
- }
- //Definition *d = md->getOutputFileBase();
- //if (d==Doxygen::globalScope) d=md->getBodyDef();
- if (sourceBrowser &&
- !(md->isLinkable() && !refLinkSource) &&
- md->getStartBodyLine()!=-1 &&
- md->getBodyDef()
- )
- {
- //printf("md->getBodyDef()=%p global=%p\n",md->getBodyDef(),Doxygen::globalScope);
-
- const int maxLineNrStr = 10;
- char anchorStr[maxLineNrStr];
- qsnprintf(anchorStr,maxLineNrStr,"l%05d",md->getStartBodyLine());
- //printf("Write object link to %s\n",md->getBodyDef()->getSourceFileBase().data());
- t << convertToDocBook(name);
- // or
- // ol.writeObjectLink(0,md->getBodyDef()->getSourceFileBase(),anchorStr,name);
- }
- else if (md->isLinkable() /*&& d && d->isLinkable()*/)
- {
- t << convertToDocBook(name);
- // or
- // ol.writeObjectLink(md->getReference(), md->getOutputFileBase(), md->anchor(),name);
- }
- else
- {
- t << convertToDocBook(name);
- }
- }
- index=newIndex+matchLen;
- }
- t << ldefLine.right(ldefLine.length()-index);
- t<< ".";
- t << "</para></formalpara>";
- }
-}
-static void generateInlineCode(FTextStream &t,const char *scopeName, Definition *def)
-{
- static bool inlineSources = Config_getBool(INLINE_SOURCES);
- //printf("Source Fragment %s: %d-%d bodyDef=%p\n",name().data(),
- // m_startBodyLine,m_endBodyLine,m_bodyDef);
- if (inlineSources && def->hasSources())
- {
- QCString codeFragment;
- int actualStart=def->getStartBodyLine(),actualEnd=def->getEndBodyLine();
- if (readCodeFragment(def->getBodyDef()->absFilePath(),
- actualStart,actualEnd,codeFragment)
- )
- {
- //printf("Adding code fragment '%s' ext='%s'\n",
- // codeFragment.data(),m_impl->defFileExt.data());
- ParserInterface *pIntf = Doxygen::parserManager->getParser(def->getDefFileExtension());
- pIntf->resetCodeParserState();
- //printf("Read:\n`%s'\n\n",codeFragment.data());
- MemberDef *thisMd = 0;
- if (def->definitionType()==Definition::TypeMember) thisMd = (MemberDef *)def;
-
- DocbookCodeGenerator *docbookGen = new DocbookCodeGenerator(t);
- docbookGen->startCodeFragment();
- pIntf->parseCode(*docbookGen, // codeOutIntf
- scopeName, // scope
- codeFragment, // input
- def->getLanguage(), // lang
- FALSE, // isExample
- 0, // exampleName
- def->getBodyDef(), // fileDef
- actualStart, // startLine
- actualEnd, // endLine
- TRUE, // inlineFragment
- thisMd, // memberDef
- TRUE // show line numbers
- );
- docbookGen->finish();
- docbookGen->endCodeFragment();
- delete docbookGen;
- }
- }
-}
-
-static void definedAtLine(int line, QCString fileName, FTextStream &t)
-{
- QCString refText = theTranslator->trDefinedAtLineInSourceFile();
- int lineMarkerPos = refText.find("@0");
- int fileMarkerPos = refText.find("@1");
- if (lineMarkerPos!=-1 && fileMarkerPos!=-1) // should always pass this.
- {
- if (lineMarkerPos<fileMarkerPos) // line marker before file marker
- {
- t << refText.left(lineMarkerPos)
- << line
- << refText.mid(lineMarkerPos+2, fileMarkerPos-lineMarkerPos-2)
- << fileName
- << refText.right(refText.length()-fileMarkerPos-2);
- }
- else // file marker before line marker
- {
- t << refText.left(fileMarkerPos)
- << fileName
- << refText.mid(fileMarkerPos+2, lineMarkerPos-fileMarkerPos-2)
- << line
- << refText.right(refText.length()-lineMarkerPos-2);
- }
- }
- else
- {
- err("translation error: invalid markers in trDefinedAtLineInSourceFile()\n");
- }
-}
-
-static void generateDocbookForMember(MemberDef *md,FTextStream &t,Definition *def, bool detailed=0)
-{
- // + declaration/definition arg lists
- // + reimplements
- // + reimplementedBy
- // + exceptions
- // + const/volatile specifiers
- // - examples
- // + source definition
- // + source references
- // + source referenced by
- // - body code
- // + template arguments
- // (templateArguments(), definitionTemplateParameterLists())
- // - call graph
-
- // enum values are written as part of the enum
- if (md->memberType()==MemberType_EnumValue) return;
- if (md->isHidden()) return;
- //if (md->name().at(0)=='@') return; // anonymous member
-
- // group members are only visible in their group
- //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return;
- QCString memType;
- switch (md->memberType())
- {
- case MemberType_Define: memType="define"; break;
- case MemberType_Function: memType="function"; break;
- case MemberType_Variable: memType="variable"; break;
- case MemberType_Typedef: memType="typedef"; break;
- case MemberType_Enumeration: memType="enum"; break;
- case MemberType_EnumValue: ASSERT(0); break;
- case MemberType_Signal: memType="signal"; break;
- case MemberType_Slot: memType="slot"; break;
- case MemberType_Friend: memType="friend"; break;
- case MemberType_DCOP: memType="dcop"; break;
- case MemberType_Property: memType="property"; break;
- case MemberType_Event: memType="event"; break;
- case MemberType_Interface: memType="interface"; break;
- case MemberType_Service: memType="service"; break;
- }
- QCString scopeName;
- if (md->getClassDef())
- {
- scopeName=md->getClassDef()->name();
- }
- else if (md->getNamespaceDef())
- {
- scopeName=md->getNamespaceDef()->name();
- }
- if (detailed==0)
- {
- t << " <para>" << endl;
- t << " <itemizedlist>" << endl;
- t << " <listitem>" << endl;
- //enum
- bool closePara=TRUE;
- if (md->memberType()==MemberType_Enumeration)
- {
- bool inLi[5]={ FALSE, FALSE, FALSE, FALSE, FALSE };
- MemberList *enumFields = md->enumFieldList();
- t << " <para><literallayout>" << memType << " <link linkend=\"_";
- if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
- {
- t << md->getGroupDef()->getOutputFileBase();
- }
- else
- {
- t << memberOutputFileBase(md);
- }
- t << "_1" << md->anchor() << "\">" << convertToDocBook(md->name()) << "</link>";
- if (enumFields!=0)
- {
- MemberListIterator emli(*enumFields);
- MemberDef *emd;
- t << " {" << endl;
- int cnt=0;
- for (emli.toFirst();(emd=emli.current());++emli)
- {
- if (cnt!=0)
- {
- t << "," << endl;
- }
- t << "<link linkend=\"_" << memberOutputFileBase(emd) << "_1" << emd->anchor() << "\">";
- writeDocbookString(t,emd->name());
- t << "</link>";
- if (!emd->initializer().isEmpty())
- {
- writeDocbookString(t,emd->initializer());
- }
- cnt++;
- }
- t << endl << "}";
- }
- t << "</literallayout>" << endl;
- if (md->briefDescription())
- {
- t << "<para><emphasis>";
- writeDocbookString(t,md->briefDescription());
- t << "</emphasis></para>" << endl;
- }
- }
- else if (md->memberType()==MemberType_Define)
- {
- t << " <para>" << "#" << memType << " <link linkend=\"_";
- if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
- {
- t << md->getGroupDef()->getOutputFileBase();
- }
- else
- {
- t << memberOutputFileBase(md);
- }
- t << "_1" << md->anchor() << "\">" << convertToDocBook(md->name()) << "</link>";
- if (!md->initializer().isEmpty() && md->initializer().length()<2000)
- {
- t << " ";
- linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->initializer());
- }
- if (md->briefDescription())
- {
- t << "<para><emphasis>";
- writeDocbookString(t,md->briefDescription());
- t << "</emphasis></para>" << endl;
- }
- }
- else if (md->memberType()==MemberType_Variable)
- {
- if (md->getClassDef())
- {
- t << " <para>" << convertToDocBook(md->declaration());
- if (md->briefDescription())
- {
- t << "<para><emphasis>";
- writeDocbookString(t,md->briefDescription());
- t << "</emphasis></para>";
- }
- }
- else
- {
- t << " <para>";
- linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->typeString());
- t << " <link linkend=\"_";
- if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
- {
- t << md->getGroupDef()->getOutputFileBase();
- }
- else
- {
- t << memberOutputFileBase(md);
- }
- t << "_1" << md->anchor() << "\">" << convertToDocBook(md->name()) << "</link>";
- if (md->briefDescription())
- {
- t << "<para><emphasis>";
- writeDocbookString(t,md->briefDescription());
- t << "</emphasis></para>" << endl;
- }
- }
- }
- else if (md->memberType()==MemberType_Typedef)
- {
- t << " <para>" << memType;
- t << " ";
- linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->typeString());
- t << " ";
- t << " <link linkend=\"_";
- if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
- {
- t << md->getGroupDef()->getOutputFileBase();
- }
- else
- {
- t << memberOutputFileBase(md);
- }
- t << "_1" << md->anchor() << "\">" << convertToDocBook(md->name()) << "</link>";
- if (md->briefDescription())
- {
- t << "<para><emphasis>";
- writeDocbookString(t,md->briefDescription());
- t << "</emphasis></para>" << endl;
- }
- }
- else if (md->memberType()==MemberType_Function)
- {
- t << " <para>";
- linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,md->typeString());
- t << " <link linkend=\"_";
- if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
- {
- t << md->getGroupDef()->getOutputFileBase();
- }
- else
- {
- t << memberOutputFileBase(md);
- }
- t << "_1" << md->anchor() << "\">" << convertToDocBook(md->name()) << "</link>";
- t << " (" << endl;
- ArgumentList *declAl = md->declArgumentList();
- if (declAl && declAl->count()>0)
- {
- ArgumentListIterator declAli(*declAl);
- Argument *a;
- int cnt=0;
- for (declAli.toFirst();(a=declAli.current());++declAli)
- {
- if (cnt!=0)
- {
- t << ", ";
- }
- if (!a->type.isEmpty())
- {
- linkifyText(TextGeneratorDocbookImpl(t),def,md->getBodyDef(),md,a->type);
- }
- t << " ";
- if (!a->name.isEmpty())
- {
- writeDocbookString(t,a->name);
- }
- cnt++;
- }
- }
- t << ")";
- if (md->briefDescription())
- {
- t << "<para><emphasis>";
- writeDocbookString(t,md->briefDescription());
- t << "</emphasis></para>" << endl;
- }
- }
- else
- {
- closePara = FALSE;
- }
- if (closePara) t << "</para>" << endl;
- t << " </listitem>" << endl;
- t << " </itemizedlist>" << endl;
- t << " </para>" << endl;
- }
- else
- {
- if (md->memberType()==MemberType_Enumeration)
- {
- MemberList *enumFields = md->enumFieldList();
- t << " <section xml:id=\"_";
- if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
- {
- t << md->getGroupDef()->getOutputFileBase();
- }
- else
- {
- t << memberOutputFileBase(md);
- }
- t << "_1" << md->anchor() << "\">" << endl;
- t << " <title>" << memType << " " << convertToDocBook(md->name()) << " " << "</title>" << endl;
- t << " ";
- writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
- t << endl;
- if (enumFields!=0)
- {
- MemberListIterator emli(*enumFields);
- MemberDef *emd;
- t << " <formalpara>" << endl;
- t << " <title>" << theTranslator->trEnumerationValues() << ":</title>" << endl;
- t << " <variablelist>" << endl;
- for (emli.toFirst();(emd=emli.current());++emli)
- {
- t << " <varlistentry xml:id=\"_";
- t << memberOutputFileBase(emd) << "_1" << emd->anchor() << "\">" << endl;
- t << " <term>";
- writeDocbookString(t,emd->name());
- t << "</term>" << endl;
- t << " <listitem>" << endl;
- if(Config_getBool(REPEAT_BRIEF))
- {
- t << " <para>";
- writeDocbookString(t,emd->briefDescription());
- t << "</para>" << endl;
- }
- t << " </listitem>" << endl;
- t << " </varlistentry>" << endl;
- }
- t << " </variablelist>" << endl;
- t << " </formalpara>" << endl;
- t << " <para>";
- t << " <para>";
- definedAtLine(md->getDefLine(),stripPath(md->getDefFileName()),t);
- t << "</para>" << endl;
-
- t << " <literallayout><computeroutput>" << endl;
- t << "{" << endl;
- for (emli.toFirst();(emd=emli.current());++emli)
- {
- writeDocbookString(t,emd->name());
- if (!emd->initializer().isEmpty())
- {
- writeDocbookString(t,emd->initializer());
- }
- t << ", " << endl;
- }
- t << "}" << convertToDocBook(md->name()) << ";" << endl;
- t << " </computeroutput></literallayout>" << endl;
- t << " </para>" << endl;
- }
- t << " </section>" << endl;
- }
- else if (md->memberType()==MemberType_Typedef)
- {
- t << " <section xml:id=\"_";
- if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
- {
- t << md->getGroupDef()->getOutputFileBase();
- }
- else
- {
- t << memberOutputFileBase(md);
- }
- t << "_1" << md->anchor() << "\">" << endl;
- t << " <title>" << convertToDocBook(md->definition()) << "</title>";
- if(Config_getBool(REPEAT_BRIEF))
- {
- t << " <emphasis>";
- writeDocbookString(t,md->briefDescription());
- t << "</emphasis>" << endl;
- }
- t << " ";
- writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
- t << endl;
- t << " </section>" << endl;
- }
- else if (md->memberType()==MemberType_Function)
- {
- t << " <section xml:id=\"_";
- if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
- {
- t << md->getGroupDef()->getOutputFileBase();
- }
- else
- {
- t << memberOutputFileBase(md);
- }
- t << "_1" << md->anchor() << "\">" << endl;
- t << " <title>" << convertToDocBook(md->definition()) << " " << convertToDocBook(md->argsString()) << "</title>";
- addIndexTerm(t,md->name(),def->name());
- addIndexTerm(t,def->name(),md->name());
- if(Config_getBool(REPEAT_BRIEF))
- {
- if (!md->briefDescription().isEmpty())
- {
- t << " <emphasis>";
- writeDocbookString(t,md->briefDescription());
- t << "</emphasis>" << endl;
- }
- }
- t << " ";
- writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
- t << endl;
-
- if (Config_getBool(REFERENCED_BY_RELATION))
- {
- generateSourceRefList(t,md->name(),theTranslator->trReferencedBy(),md->getReferencedByMembers(),md);
- }
- if (Config_getBool(REFERENCES_RELATION))
- {
- generateSourceRefList(t,md->name(),theTranslator->trReferences(),md->getReferencesMembers(),md);
- }
- generateInlineCode(t,md->name(),md);
- t << " </section>" << endl;
- }
- else if (md->memberType()==MemberType_Define)
- {
- if (md->documentation())
- {
- t << " <section xml:id=\"_";
- if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
- {
- t << md->getGroupDef()->getOutputFileBase();
- }
- else
- {
- t << memberOutputFileBase(md);
- }
- t << "_1" << md->anchor() << "\">" << endl;
- t << " <title>" << convertToDocBook(md->definition()) << "</title>";
- t << " ";
- writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
- t << endl;
- t << " </section>" << endl;
- }
- }
- else if (md->memberType()==MemberType_Variable)
- {
- if (md->getClassDef())
- {
- if (md->documentation())
- {
- t << " <section xml:id=\"_";
- if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
- {
- t << md->getGroupDef()->getOutputFileBase();
- }
- else
- {
- t << memberOutputFileBase(md);
- }
- t << "_1" << md->anchor() << "\">" << endl;
- t << " <title>" << convertToDocBook(md->definition()) << "</title>";
- addIndexTerm(t,md->name(),def->name());
- addIndexTerm(t,def->name(),md->name());
- t << " ";
- writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
- t << endl;
- t << " </section>" << endl;
- }
- }
- else
- {
- t << " <section xml:id=\"_";
- if (md->getGroupDef() && def->definitionType()==Definition::TypeGroup)
- {
- t << md->getGroupDef()->getOutputFileBase();
- }
- else
- {
- t << memberOutputFileBase(md);
- }
- t << "_1" << md->anchor() << "\">" << endl;
- t << " <title>" << convertToDocBook(md->definition()) << "</title>";
- addIndexTerm(t,md->name(),def->name());
- addIndexTerm(t,def->name(),md->name());
- if(Config_getBool(REPEAT_BRIEF))
- {
- t << " <emphasis>";
- writeDocbookString(t,md->briefDescription());
- t << "</emphasis>" << endl;
- }
- t << " ";
- writeDocbookDocBlock(t,md->docFile(),md->docLine(),md->getOuterScope(),md,md->documentation());
- t << endl;
- t << " </section>" << endl;
- }
- }
- }
-}
-
-static void generateDocbookSection(Definition *d,FTextStream &t,MemberList *ml,const char *,
- bool detailed=0, const char *header=0,const char *documentation=0)
-{
- if (ml==0) return;
- MemberListIterator mli(*ml);
- MemberDef *md;
- int count=0;
- int doc_count=0;
- QCString title, desctitle, subtitle;
-
- for (mli.toFirst();(md=mli.current());++mli)
- {
- // namespace members are also inserted in the file scope, but
- // to prevent this duplication in the Docbook output, we filter those here.
- if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
- {
- count++;
- }
- }
-
- if (count==0) return; // empty list
-
- subtitle = "";
- switch (ml->listType())
- {
- case MemberListType_pubMethods: d->getLanguage()==SrcLangExt_ObjC ? title = theTranslator->trInstanceMethods() : title = theTranslator->trPublicMembers();
- switch (d->getLanguage())
- {
- case SrcLangExt_ObjC: desctitle = theTranslator->trMethodDocumentation(); break;
- case SrcLangExt_Fortran: desctitle = theTranslator->trMemberFunctionDocumentationFortran(); break;
- default: desctitle = theTranslator->trMemberFunctionDocumentation(); break;
- };
- break;
- case MemberListType_priMethods: title=theTranslator->trPrivateMembers(); desctitle=""; break;
-
- case MemberListType_decTypedefMembers: title=theTranslator->trTypedefs(); desctitle=theTranslator->trTypedefDocumentation(); break;
- case MemberListType_decEnumMembers: title=theTranslator->trEnumerations(); desctitle=theTranslator->trEnumerationTypeDocumentation(); break;
- case MemberListType_decFuncMembers: title=theTranslator->trFunctions(); desctitle=theTranslator->trFunctionDocumentation(); break;
- case MemberListType_decVarMembers: title=theTranslator->trVariables(); desctitle=theTranslator->trVariableDocumentation(); break;
- case MemberListType_pubAttribs: title=theTranslator->trPublicAttribs(); desctitle=theTranslator->trMemberDataDocumentation(); break;
- case MemberListType_priAttribs: title=theTranslator->trPrivateAttribs(); desctitle=theTranslator->trMemberDataDocumentation(); break;
- case MemberListType_proAttribs: title=theTranslator->trProtectedAttribs(); desctitle=theTranslator->trMemberDataDocumentation(); break;
- case MemberListType_decDefineMembers: title=theTranslator->trDefines(); desctitle=theTranslator->trDefineDocumentation(); break;
- case MemberListType_related: title=theTranslator->trRelatedFunctions(); desctitle=theTranslator->trRelatedFunctionDocumentation();
- subtitle=theTranslator->trRelatedSubscript(); break;
- default: title=""; desctitle="";
- }
-
- if (detailed)
- {
- for (mli.toFirst();(md=mli.current());++mli)
- {
- if (md->documentation().isEmpty() && !Config_getBool(REPEAT_BRIEF))
- {
- continue;
- }
- doc_count = 1;
- break;
- }
-
- if(doc_count == 0) return;
-
- if (!QCString(header).isEmpty())
- {
- t << " <section>" << endl;
- t << " <title>" << convertToDocBook(header) << "</title>" << endl;
- }
- else if (desctitle)
- {
- t << " <section>" << endl;
- t << " <title>" << desctitle << "</title>" << endl;
- }
- }
- else
- {
- t << " <section>" << endl;
- if (!QCString(header).isEmpty())
- {
- t << " <title>" << convertToDocBook(header) << "</title>" << endl;
- }
- else
- {
- t << " <title>" << title << "</title>" << endl;
- }
- if (!subtitle.isEmpty())
- t << " <para>" << subtitle << "</para>" << endl;
- }
-
- if (documentation)
- {
- t << " <description>";
- writeDocbookDocBlock(t,d->docFile(),d->docLine(),d,0,documentation);
- t << "</description>" << endl;
- }
- for (mli.toFirst();(md=mli.current());++mli)
- {
- // namespace members are also inserted in the file scope, but
- // to prevent this duplication in the Docbook output, we filter those here.
- if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
- {
- if (detailed && md->documentation().isEmpty() && !Config_getBool(REPEAT_BRIEF))
- {
- continue;
- }
-
- generateDocbookForMember(md,t,d,detailed);
- }
- }
- if (detailed)
- {
- if (!QCString(header).isEmpty())
- {
- t << " </section>" << endl;
- }
- else if (desctitle)
- {
- t << " </section>" << endl;
- }
- }
- else
- {
- t << " </section>" << endl;
- }
-}
-
-static void writeInnerClasses(const ClassSDict *cl,FTextStream &t)
-{
- if (cl)
- {
- ClassSDict::Iterator cli(*cl);
- ClassDef *cd;
- QCString title = theTranslator->trClasses();
-
- if (cli.toFirst())
- {
- t << " <section>" << endl;
- t << " <title> " << title << " </title>" << endl;
- }
- for (cli.toFirst();(cd=cli.current());++cli)
- {
- if (!cd->isHidden() && cd->name().find('@')==-1)
- {
- t << " <para>" << endl;
- t << " <itemizedlist>" << endl;
- t << " <listitem>" << endl;
- t << " <para>" << "struct <link linkend=\"_" << classOutputFileBase(cd) << "\">" << convertToDocBook(cd->name()) << "</link>";
- t << "</para>" << endl;
- if (cd->briefDescription())
- {
- t << "<para><emphasis>";
- writeDocbookString(t,cd->briefDescription());
- t << "</emphasis></para>" << endl;
- }
- t << " </listitem>" << endl;
- t << " </itemizedlist>" << endl;
- t << " </para>" << endl;
- }
- }
- if (cli.toFirst())
- {
- t << " </section>" << endl;
- }
- }
-}
-
-static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t)
-{
- if (nl)
- {
- NamespaceSDict::Iterator nli(*nl);
- NamespaceDef *nd;
- QCString title = theTranslator->trNamespaces();
-
- if (nli.toFirst())
- {
- t << " <simplesect>" << endl;
- t << " <title> " << title << " </title>" << endl;
- }
- for (nli.toFirst();(nd=nli.current());++nli)
- {
- if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes
- {
- t << " <para>" << endl;
- t << " <itemizedlist>" << endl;
- t << " <listitem>" << endl;
- t << " <para>" << "struct <link linkend=\"_" << nd->getOutputFileBase() << "\">" << convertToDocBook(nd->name()) << "</link>";
- t << "</para>" << endl;
- t << " </listitem>" << endl;
- t << " </itemizedlist>" << endl;
- t << " </para>" << endl;
- }
- }
- if (nli.toFirst())
- {
- t << " </simplesect>" << endl;
- }
- }
-}
-
-static void writeInnerFiles(const FileList *fl,FTextStream &t)
-{
- if (fl)
- {
- QListIterator<FileDef> fli(*fl);
- FileDef *fd;
- QCString title = theTranslator->trFile(TRUE,TRUE);
-
- if (fli.toFirst())
- {
- t << " <simplesect>" << endl;
- t << " <title> " << title << " </title>" << endl;
- }
- for (fli.toFirst();(fd=fli.current());++fli)
- {
- t << " <para>" << endl;
- t << " <itemizedlist>" << endl;
- t << " <listitem>" << endl;
- t << " <para>" << "file <link linkend=\"_" << fd->getOutputFileBase() << "\">" << convertToDocBook(fd->name()) << "</link>";
- t << "</para>" << endl;
- t << " </listitem>" << endl;
- t << " </itemizedlist>" << endl;
- t << " </para>" << endl;
- }
- if (fli.toFirst())
- {
- t << " </simplesect>" << endl;
- }
- }
-}
-
-static void writeInnerPages(const PageSDict *pl,FTextStream &t)
-{
- if (pl)
- {
- PageSDict::Iterator pli(*pl);
- PageDef *pd;
-
- for (pli.toFirst();(pd=pli.current());++pli)
- {
- t << "<xi:include href=\"" << pd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
- }
- }
-}
-
-static void writeInnerGroups(const GroupList *gl,FTextStream &t)
-{
- if (gl)
- {
- GroupListIterator gli(*gl);
- GroupDef *sgd;
-
- //Docbook header tags for inner groups
- if (gli.toFirst())
- {
- t << " <simplesect>" << endl;
- t << " <title>" << theTranslator->trModules() << "</title>" << endl;
- t << " </simplesect>" << endl;
- t << " <para>" << endl;
- t << " <itemizedlist>" << endl;
- }
-
- for (gli.toFirst();(sgd=gli.current());++gli)
- {
- t << " <listitem><para><link linkend=\"_" << sgd->getOutputFileBase() << "\">" << convertToDocBook(sgd->groupTitle()) << "</link></para></listitem>" << endl;
- }
-
- //Docbook footer tags for inner groups
- if (gli.toFirst())
- {
- t << " </itemizedlist>" << endl;
- t << " </para>" << endl;
- }
-
- }
-}
-
-static void writeInnerDirs(const DirList *dl,FTextStream &t)
-{
- if (dl)
- {
- QListIterator<DirDef> subdirs(*dl);
- DirDef *subdir;
- QCString title = theTranslator->trDirectories();
- if (subdirs.toFirst())
- {
- t << " <simplesect>" << endl;
- t << " <title> " << title << " </title>" << endl;
- }
- for (subdirs.toFirst();(subdir=subdirs.current());++subdirs)
- {
- t << " <para>" << endl;
- t << " <itemizedlist>" << endl;
- t << " <listitem>" << endl;
- t << " <para>" << "dir <link linkend=\"_" << subdir->getOutputFileBase() << "\">" << convertToDocBook(subdir->displayName()) << "</link>";
- t << "</para>" << endl;
- t << " </listitem>" << endl;
- t << " </itemizedlist>" << endl;
- t << " </para>" << endl;
- }
- if (subdirs.toFirst())
- {
- t << " </simplesect>" << endl;
- }
- }
-}
-
-static void writeInnerGroupFiles(const GroupList *gl,FTextStream &t)
-{
- if (gl)
- {
- GroupListIterator gli(*gl);
- GroupDef *sgd;
-
- for (gli.toFirst();(sgd=gli.current());++gli)
- {
- t << "<xi:include href=\"" << sgd->getOutputFileBase() << ".xml\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
- }
- }
-}
-
-static void generateDocbookForClass(ClassDef *cd,FTextStream &ti)
-{
- // + brief description
- // + detailed description
- // + template argument list(s)
- // - include file
- // + member groups
- // + inheritance diagram
- // + list of direct super classes
- // + list of direct sub classes
- // + list of inner classes
- // + collaboration diagram
- // + list of all members
- // + user defined member sections
- // + standard member sections
- // + detailed member documentation
- // - examples using the class
-
- if (cd->isReference()) return; // skip external references.
- if (cd->isHidden()) return; // skip hidden classes.
- if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
- if (cd->templateMaster()!=0) return; // skip generated template instances.
-
- msg("Generating Docbook output for class %s\n",cd->name().data());
-
- QCString fileDocbook=cd->getOutputFileBase()+".xml";
- //Add the file Documentation info to index file
- ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
-
- QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT);
- QCString fileName=outputDirectory+"/"+ classOutputFileBase(cd)+".xml";
- QCString relPath = relativePathToRoot(fileName);
- QFile f(fileName);
- if (!f.open(IO_WriteOnly))
- {
- err("Cannot open file %s for writing!\n",fileName.data());
- return;
- }
- FTextStream t(&f);
- //t.setEncoding(FTextStream::UnicodeUTF8);
-
- writeDocbookHeader_ID(t, classOutputFileBase(cd));
- t << "<title>";
- writeDocbookString(t,cd->name());
- addIndexTerm(t,cd->name());
- t << " " << cd->compoundTypeString() << " Reference";
- t << "</title>" << endl;
- if (cd->briefDescription())
- {
- t << " <para>" << endl;
- writeDocbookDocBlock(t,cd->briefFile(),cd->briefLine(),cd,0,cd->briefDescription());
- t << " </para>" << endl;
- }
-
- IncludeInfo *ii=cd->includeInfo();
- if (ii)
- {
- QCString nm = ii->includeName;
- if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
- if (!nm.isEmpty())
- {
- t << "<para>" << endl;
- t << " <programlisting>#include ";
- if (ii->fileDef && !ii->fileDef->isReference()) // TODO: support external references
- {
- t << "<link linkend=\"_" << ii->fileDef->getOutputFileBase() << "\">";
- }
- if (ii->local)
- {
- t << "&quot;";
- }
- else
- {
- t << "&lt;";
- }
- t << convertToDocBook(nm);
- if (ii->local)
- {
- t << "&quot;";
- }
- else
- {
- t << "&gt;";
- }
- if (ii->fileDef && !ii->fileDef->isReference())
- {
- t << "</link>";
- }
- t << "</programlisting>" << endl;
- t << "</para>" << endl;
- }
- }
-
- if (Config_getBool(HAVE_DOT) && (Config_getBool(CLASS_DIAGRAMS) || Config_getBool(CLASS_GRAPH)))
- {
- t << "<para>Inheritance diagram for " << convertToDocBook(cd->name()) << "</para>" << endl;
- DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
- inheritanceGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,TRUE,FALSE);
- }
-
- if (Config_getBool(HAVE_DOT) && Config_getBool(COLLABORATION_GRAPH))
- {
- t << "<para>Collaboration diagram for " << convertToDocBook(cd->name()) << "</para>" << endl;
- DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
- collaborationGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,TRUE,FALSE);
- }
-
- writeInnerClasses(cd->getClassSDict(),t);
-
- writeTemplateList(cd,t);
- if (cd->getMemberGroupSDict())
- {
- MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
- MemberGroup *mg;
- for (;(mg=mgli.current());++mgli)
- {
- generateDocbookSection(cd,t,mg->members(),"user-defined",0,mg->header(),
- mg->documentation());
- }
- }
-
- QListIterator<MemberList> mli(cd->getMemberLists());
- MemberList *ml;
- for (mli.toFirst();(ml=mli.current());++mli)
- {
- if ((ml->listType()&MemberListType_detailedLists)==0)
- {
- generateDocbookSection(cd,t,ml,g_docbookSectionMapper.find(ml->listType()));
- }
- }
-
- if ((Config_getBool(REPEAT_BRIEF) && cd->briefDescription()) || cd->documentation())
- {
- t << " <simplesect>" << endl;
- t << " <title>" << theTranslator->trDetailedDescription() << "</title>" << endl;
-
- if(Config_getBool(REPEAT_BRIEF))
- {
- if (cd->briefDescription())
- {
- t << " <para>" << endl;
- // A title as 'Brief Description' may not be necessary.
- //t << " <title>" << theTranslator->trBriefDescription() << "</title>" << endl;
- writeDocbookDocBlock(t,cd->briefFile(),cd->briefLine(),cd,0,cd->briefDescription());
- t << " </para>" << endl;
- }
- }
-
- if (cd->documentation())
- {
- writeDocbookDocBlock(t,cd->docFile(),cd->docLine(),cd,0,cd->documentation());
- }
- t << " </simplesect>" << endl;
- }
-
- if (cd->getMemberGroupSDict())
- {
- MemberGroupSDict::Iterator mgli(*cd->getMemberGroupSDict());
- MemberGroup *mg;
- for (;(mg=mgli.current());++mgli)
- {
- generateDocbookSection(cd,t,mg->members(),"user-defined",1,mg->header(),
- mg->documentation());
- }
- }
-
- for (mli.toFirst();(ml=mli.current());++mli)
- {
- if ((ml->listType()&MemberListType_detailedLists)==0)
- {
- generateDocbookSection(cd,t,ml,g_docbookSectionMapper.find(ml->listType()),1);
- }
- }
-
- /*// TODO: Handling of Inheritance and Colloboration graph for Docbook to be implemented
- DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
- if (!inheritanceGraph.isTrivial())
- {
- t << " <inheritancegraph>" << endl;
- inheritanceGraph.writeDocbook(t);
- t << " </inheritancegraph>" << endl;
- }
- DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
- if (!collaborationGraph.isTrivial())
- {
- t << " <collaborationgraph>" << endl;
- collaborationGraph.writeDocbook(t);
- t << " </collaborationgraph>" << endl;
- }
- t << " <location file=\""
- << cd->getDefFileName() << "\" line=\""
- << cd->getDefLine() << "\"";
- if (cd->getStartBodyLine()!=-1)
- {
- FileDef *bodyDef = cd->getBodyDef();
- if (bodyDef)
- {
- t << " bodyfile=\"" << bodyDef->absFilePath() << "\"";
- }
- t << " bodystart=\"" << cd->getStartBodyLine() << "\" bodyend=\""
- << cd->getEndBodyLine() << "\"";
- }
- t << "/>" << endl;
- writeListOfAllMembers(cd,t);
- */
-
- t << " <para>" << cd->generatedFromFiles() << "</para>" << endl;
- t << " <para><itemizedlist><listitem><para>" << stripPath(cd->getDefFileName()) << "</para></listitem></itemizedlist></para>" << endl;
- t << "</section>" << endl;
-
-}
-
-static void generateDocbookForNamespace(NamespaceDef *nd,FTextStream &ti)
-{
- // + contained class definitions
- // + contained namespace definitions
- // + member groups
- // + normal members
- // + brief desc
- // + detailed desc
- // + location
- // - files containing (parts of) the namespace definition
-
- if (nd->isReference() || nd->isHidden()) return; // skip external references
-
- QCString fileDocbook=nd->getOutputFileBase()+".xml";
- //Add the file Documentation info to index file
- ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
-
- QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT);
- QCString fileName=outputDirectory+"/"+nd->getOutputFileBase()+".xml";
- QFile f(fileName);
- if (!f.open(IO_WriteOnly))
- {
- err("Cannot open file %s for writing!\n",fileName.data());
- return;
- }
- FTextStream t(&f);
- //t.setEncoding(FTextStream::UnicodeUTF8);
-
- writeDocbookHeader_ID(t, nd->getOutputFileBase());
- t << "<title>";
- addIndexTerm(t,nd->displayName());
- writeDocbookString(t,nd->title());
- t << "</title>" << endl;
-
- if (nd->briefDescription())
- {
- t << " <para>" << endl;
- //t << " <title>" << theTranslator->trBriefDescription() << "</title>" << endl;
- t << " </para>" << endl;
- }
- writeInnerClasses(nd->getClassSDict(),t);
- writeInnerNamespaces(nd->getNamespaceSDict(),t);
-
- if (nd->getMemberGroupSDict())
- {
- MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
- MemberGroup *mg;
- for (;(mg=mgli.current());++mgli)
- {
- generateDocbookSection(nd,t,mg->members(),"user-defined",0,mg->header(),
- mg->documentation());
- }
- }
-
- QListIterator<MemberList> mli(nd->getMemberLists());
- MemberList *ml;
- for (mli.toFirst();(ml=mli.current());++mli)
- {
- if ((ml->listType()&MemberListType_declarationLists)!=0)
- {
- generateDocbookSection(nd,t,ml,g_docbookSectionMapper.find(ml->listType()));
- }
- }
-
- if ((Config_getBool(REPEAT_BRIEF) && nd->briefDescription()) || nd->documentation())
- {
- t << " <simplesect>" << endl;
- t << " <title>" << theTranslator->trDetailedDescription() << "</title>" << endl;
-
- if(Config_getBool(REPEAT_BRIEF))
- {
- if (nd->briefDescription())
- {
- t << " <para>" << endl;
- //t << " <title>" << theTranslator->trBriefDescription() << "</title>" << endl;
- writeDocbookDocBlock(t,nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription());
- t << " </para>" << endl;
- }
- }
-
- if (nd->documentation())
- {
- writeDocbookDocBlock(t,nd->docFile(),nd->docLine(),nd,0,nd->documentation());
- }
- t << " </simplesect>" << endl;
- }
-
- if (nd->getMemberGroupSDict())
- {
- MemberGroupSDict::Iterator mgli(*nd->getMemberGroupSDict());
- MemberGroup *mg;
- for (;(mg=mgli.current());++mgli)
- {
- generateDocbookSection(nd,t,mg->members(),"user-defined",1,mg->header(),
- mg->documentation());
- }
- }
-
- for (mli.toFirst();(ml=mli.current());++mli)
- {
- if ((ml->listType()&MemberListType_detailedLists)==0)
- {
- if (ml->listType() != MemberListType_allMembersList &&
- ml->listType() != MemberListType_docFuncMembers)
- generateDocbookSection(nd,t,ml,g_docbookSectionMapper.find(ml->listType()),1);
- }
- }
- // we actually need here "namespace"
- // t << " <para>" << theTranslator->trGeneratedFromFiles(ClassDef::Struct, FALSE) << "</para>" << endl;
- // t << " <para><itemizedlist><listitem><para>" << stripPath(nd->getDefFileName()) << "</para></listitem></itemizedlist></para>" << endl;
- t << "</section>" << endl;
-}
-
-static void generateDocbookForFile(FileDef *fd,FTextStream &ti)
-{
- // + includes files
- // + includedby files
- // + include graph
- // + included by graph
- // + contained class definitions
- // + contained namespace definitions
- // + member groups
- // + normal members
- // + brief desc
- // + detailed desc
- // + source code
- // + location
- // - number of lines
-
- if (fd->isReference()) return; // skip external references
-
- QCString fileDocbook=fd->getOutputFileBase()+".xml";
- //Add the file Documentation info to index file
- ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
-
- QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT);
- QCString fileName=outputDirectory+"/"+fd->getOutputFileBase()+".xml";
- QCString relPath = relativePathToRoot(fileName);
-
- QFile f(fileName);
- if (!f.open(IO_WriteOnly))
- {
- err("Cannot open file %s for writing!\n",fileName.data());
- return;
- }
- FTextStream t(&f);
- //t.setEncoding(FTextStream::UnicodeUTF8);
- writeDocbookHeader_ID(t, fd->getOutputFileBase());
-
- t << " <title>";
- writeDocbookString(t,fd->name());
- t << " File Reference";
- t << "</title>" << endl;
-
- if (fd->briefDescription())
- {
- t << " <para>" << endl;
- writeDocbookDocBlock(t,fd->briefFile(),fd->briefLine(),fd,0,fd->briefDescription());
- t << " </para>" << endl;
- }
-
- IncludeInfo *inc;
-
- if (fd->includeFileList())
- {
- QListIterator<IncludeInfo> ili1(*fd->includeFileList());
- for (ili1.toFirst();(inc=ili1.current());++ili1)
- {
- t << " <programlisting>#include ";
- if (inc->local)
- {
- t << "&quot;";
- }
- else
- {
- t << "&lt;";
- }
- t << convertToDocBook(inc->includeName);
- if (inc->local)
- {
- t << "&quot;";
- }
- else
- {
- t << "&gt;";
- }
- t << "</programlisting>" << endl;
- }
- }
- if (Config_getBool(HAVE_DOT))
- {
- if (Config_getBool(INCLUDE_GRAPH))
- {
- t << "<para>Include dependency diagram for " << convertToDocBook(fd->name()) << "</para>" << endl;
- DotInclDepGraph idepGraph(fd, FALSE);
- idepGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,FALSE);
- }
- if (Config_getBool(INCLUDED_BY_GRAPH))
- {
- t << "<para>Included by dependency diagram for " << convertToDocBook(fd->name()) << "</para>" << endl;
- DotInclDepGraph ibdepGraph(fd, TRUE);
- ibdepGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,FALSE);
- }
- }
-
- if (fd->getClassSDict())
- {
- writeInnerClasses(fd->getClassSDict(),t);
- }
- if (fd->getNamespaceSDict())
- {
- writeInnerNamespaces(fd->getNamespaceSDict(),t);
- }
-
- if (fd->getMemberGroupSDict())
- {
- MemberGroupSDict::Iterator mgli(*fd->getMemberGroupSDict());
- MemberGroup *mg;
- for (;(mg=mgli.current());++mgli)
- {
- generateDocbookSection(fd,t,mg->members(),"user-defined",0,mg->header(),
- mg->documentation());
- }
- }
-
- QListIterator<MemberList> mli(fd->getMemberLists());
- MemberList *ml;
- for (mli.toFirst();(ml=mli.current());++mli)
- {
- if ((ml->listType()&MemberListType_declarationLists)!=0)
- {
- generateDocbookSection(fd,t,ml,g_docbookSectionMapper.find(ml->listType()));
- }
- }
-
- t << " <simplesect>" << endl;
- t << " <title>" << theTranslator->trDetailedDescription() << "</title>" << endl;
- if(Config_getBool(REPEAT_BRIEF))
- {
- if (fd->briefDescription())
- {
- writeDocbookDocBlock(t,fd->briefFile(),fd->briefLine(),fd,0,fd->briefDescription());
- }
- }
- writeDocbookDocBlock(t,fd->docFile(),fd->docLine(),fd,0,fd->documentation());
- if (Config_getBool(FULL_PATH_NAMES))
- {
- t << " <para>Definition in file " << fd->getDefFileName() << "</para>" << endl;
- }
- else
- {
- t << " <para>Definition in file " << stripPath(fd->getDefFileName()) << "</para>" << endl;
- }
- t << " </simplesect>" << endl;
-
- for (mli.toFirst();(ml=mli.current());++mli)
- {
- if ((ml->listType()&MemberListType_declarationLists)!=0)
- {
- generateDocbookSection(fd,t,ml,g_docbookSectionMapper.find(ml->listType()),1);
- }
- }
-
- if (Config_getBool(DOCBOOK_PROGRAMLISTING))
- {
- t << " <literallayout><computeroutput>" << endl;;
- writeDocbookCodeBlock(t,fd);
- t << " </computeroutput></literallayout>" << endl;
- }
-
- t << "</section>" << endl;
-}
-
-static void generateDocbookForGroup(GroupDef *gd,FTextStream &ti)
-{
- // + members
- // + member groups
- // + files
- // + classes
- // + namespaces
- // - packages
- // + pages
- // + child groups
- // - examples
- // + brief description
- // + detailed description
-
- if (gd->isReference()) return; // skip external references
-
- if (!gd->isASubGroup())
- {
- QCString fileDocbook=gd->getOutputFileBase()+".xml";
- //Add the file Documentation info to index file
- ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
- }
-
- QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT);
- QCString fileName=outputDirectory+"/"+gd->getOutputFileBase()+".xml";
- QCString relPath = relativePathToRoot(fileName);
-
- QFile f(fileName);
- if (!f.open(IO_WriteOnly))
- {
- err("Cannot open file %s for writing!\n",fileName.data());
- return;
- }
-
- FTextStream t(&f);
- //t.setEncoding(FTextStream::UnicodeUTF8);
- writeDocbookHeader_ID(t, gd->getOutputFileBase());
-
- t << " <title>" << convertToDocBook(gd->groupTitle()) << "</title>" << endl;
- if (gd->briefDescription())
- {
- t << " <para>" << endl;
- writeDocbookDocBlock(t,gd->briefFile(),gd->briefLine(),gd,0,gd->briefDescription());
- t << " </para>" << endl;
- }
-
- if (Config_getBool(GROUP_GRAPHS) && Config_getBool(HAVE_DOT))
- {
- t << "<para>Collaboration diagram for " << convertToDocBook(gd->groupTitle()) << "</para>" << endl;
- DotGroupCollaboration collaborationGraph(gd);
- collaborationGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,FALSE);
- }
-
- writeInnerFiles(gd->getFiles(),t);
- writeInnerClasses(gd->getClasses(),t);
- writeInnerNamespaces(gd->getNamespaces(),t);
- writeInnerPages(gd->getPages(),t);
- writeInnerGroups(gd->getSubGroups(),t);
-
- if (gd->getMemberGroupSDict())
- {
- MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
- MemberGroup *mg;
- for (;(mg=mgli.current());++mgli)
- {
- generateDocbookSection(gd,t,mg->members(),"user-defined",0,mg->header(),
- mg->documentation());
- }
- }
-
- QListIterator<MemberList> mli(gd->getMemberLists());
- MemberList *ml;
- for (mli.toFirst();(ml=mli.current());++mli)
- {
- if ((ml->listType()&MemberListType_declarationLists)!=0)
- {
- generateDocbookSection(gd,t,ml,g_docbookSectionMapper.find(ml->listType()));
- }
- }
-
- if(Config_getBool(REPEAT_BRIEF))
- {
- if (gd->briefDescription())
- {
- //t << " <section>" << endl;
- //t << " <title>" << theTranslator->trBriefDescription() << "</title>" << endl;
- writeDocbookDocBlock(t,gd->briefFile(),gd->briefLine(),gd,0,gd->briefDescription());
- //t << " </section>" << endl;
- }
- }
-
- if (gd->documentation())
- {
- t << " <simplesect>" << endl;
- t << " <title>" << theTranslator->trDetailedDescription() << "</title>" << endl;
- writeDocbookDocBlock(t,gd->docFile(),gd->docLine(),gd,0,gd->documentation());
- t << " </simplesect>" << endl;
- }
-
- for (mli.toFirst();(ml=mli.current());++mli)
- {
- if ((ml->listType()&MemberListType_declarationLists)!=0)
- {
- generateDocbookSection(gd,t,ml,g_docbookSectionMapper.find(ml->listType()),1);
- }
- }
-
- writeInnerGroupFiles(gd->getSubGroups(),t);
-
- t << "</section>" << endl;
-
-}
-
-static void generateDocbookForDir(DirDef *dd,FTextStream &ti)
-{
- if (dd->isReference()) return; // skip external references
-
- QCString fileDocbook=dd->getOutputFileBase()+".xml";
- //Add the file Documentation info to index file
- ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
-
- QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT);
- QCString fileName=outputDirectory+"/"+dd->getOutputFileBase()+".xml";
- QFile f(fileName);
- QCString relPath = relativePathToRoot(fileName);
-
- if (!f.open(IO_WriteOnly))
- {
- err("Cannot open file %s for writing!\n",fileName.data());
- return;
- }
-
- FTextStream t(&f);
- //t.setEncoding(FTextStream::UnicodeUTF8);
- writeDocbookHeader_ID(t, dd->getOutputFileBase());
-
- t << " <title>";
- t << theTranslator->trDirReference(dd->displayName());
- t << "</title>" << endl;
- if (dd->briefDescription())
- {
- writeDocbookDocBlock(t,dd->briefFile(),dd->briefLine(),dd,0,dd->briefDescription());
- }
- if (Config_getBool(DIRECTORY_GRAPH) && Config_getBool(HAVE_DOT))
- {
- t << "<para>Directory dependency diagram for " << convertToDocBook(dd->displayName()) << "</para>" << endl;
- DotDirDeps dirdepGraph(dd);
- dirdepGraph.writeGraph(t,GOF_BITMAP,EOF_DocBook,Config_getString(DOCBOOK_OUTPUT),fileName,relPath,FALSE);
- }
-
- writeInnerDirs(&dd->subDirs(),t);
- writeInnerFiles(dd->getFiles(),t);
-
- t << " <simplesect>" << endl;
- t << " <title>" << theTranslator->trDetailedDescription() << "</title>" << endl;
- if (dd->briefDescription())
- {
- t << " <para>" << endl;
- writeDocbookDocBlock(t,dd->briefFile(),dd->briefLine(),dd,0,dd->briefDescription());
- t << " </para>" << endl;
- }
- writeDocbookDocBlock(t,dd->docFile(),dd->docLine(),dd,0,dd->documentation());
- t << " <para>Directory location is " << dd->name() << "</para>" << endl;
- t << " </simplesect>" << endl;
-
- t << "</section>" << endl;
-}
-
-static void generateDocbookForPage(PageDef *pd,FTextStream &ti,bool isExample)
-{
- // + name
- // + title
- // + documentation
-
- if (pd->isReference()) return;
-
- QCString pageName = pd->getOutputFileBase();
- if (pd->getGroupDef())
- {
- pageName+=(QCString)"_"+pd->name();
- }
- if (pageName=="index")
- {
- pageName="mainpage"; // to prevent overwriting the generated index page.
- }
-
- QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT);
- QCString fileName=outputDirectory+"/"+pageName+".xml";
- QFile f(fileName);
- if (!f.open(IO_WriteOnly))
- {
- err("Cannot open file %s for writing!\n",fileName.data());
- return;
- }
-
- FTextStream t(&f);
- //t.setEncoding(FTextStream::UnicodeUTF8);
-
- if(isExample)
- {
- QCString fileDocbook=pageName+".xml";
- ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
- }
-
- if (!pd->hasParentPage() && !isExample)
- {
- QCString fileDocbook=pageName+".xml";
- //Add the file Documentation info to index file
- ti << " <xi:include href=\"" << fileDocbook << "\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"/>" << endl;
- writeDocbookHeaderMainpage(t,pageName);
- }
- else
- {
- QCString pid;
- if(isExample)
- {
- pid = pageName;
- }
- else
- {
- pid = pageName+"_1"+pageName;
- }
- writeDocbookHeader_ID(t, pid);
- }
-
- SectionInfo *si = Doxygen::sectionDict->find(pd->name());
- if (si)
- {
- if ( pageName == "mainpage")
- t << " <title>" << convertToDocBook(theTranslator->trMainPage()) << "</title>" << endl;
- else
- t << " <title>" << convertToDocBook(si->title) << "</title>" << endl;
- }
- else
- {
- t << " <title>" << convertToDocBook(pd->name()) << "</title>" << endl;
- }
-
- generateTOC(t, pd);
- if (isExample)
- {
- writeDocbookDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
- pd->documentation()+"\n\\include "+pd->name());
- }
- else
- {
- writeDocbookDocBlock(t,pd->docFile(),pd->docLine(),pd,0,
- pd->documentation());
- }
- writeInnerPages(pd->getSubPages(),t);
-
- if (!pd->hasParentPage() && !isExample)
- {
- t << endl << "</chapter>" << endl;
- }
- else
- {
- t << endl << "</section>" << endl;
- }
-}
-void generateDocbook_v1()
-{
-
- // + classes
- // + namespaces
- // + files
- // + groups
- // + related pages
- // - examples
-
- QCString outputDirectory = Config_getString(DOCBOOK_OUTPUT);
- if (outputDirectory.isEmpty())
- {
- outputDirectory=QDir::currentDirPath().utf8();
- }
- else
- {
- QDir dir(outputDirectory);
- if (!dir.exists())
- {
- dir.setPath(QDir::currentDirPath());
- if (!dir.mkdir(outputDirectory))
- {
- err("tag DOCBOOK_OUTPUT: Output directory `%s' does not "
- "exist and cannot be created\n",outputDirectory.data());
- exit(1);
- }
- else
- {
- msg("Notice: Output directory `%s' does not exist. "
- "I have created it for you.\n", outputDirectory.data());
- }
- dir.cd(outputDirectory);
- }
- outputDirectory=dir.absPath().utf8();
- }
-
- QDir dir(outputDirectory);
- if (!dir.exists())
- {
- dir.setPath(QDir::currentDirPath());
- if (!dir.mkdir(outputDirectory))
- {
- err("Cannot create directory %s\n",outputDirectory.data());
- return;
- }
- }
- QDir docbookDir(outputDirectory);
- createSubDirs(docbookDir);
-
- QCString fileName=outputDirectory+"/index.xml";
- QCString dbk_projectName = Config_getString(PROJECT_NAME);
- QFile f(fileName);
-
- f.setName(fileName);
- if (!f.open(IO_WriteOnly))
- {
- err("Cannot open file %s for writing!\n",fileName.data());
- return;
- }
- FTextStream t(&f);
- //t.setEncoding(FTextStream::UnicodeUTF8);
-
- // write index header for Docbook which calls the structure file
- t << "<?xml version='1.0' encoding='UTF-8' standalone='no'?>" << endl;;
- t << "<book xmlns=\"http://docbook.org/ns/docbook\" version=\"5.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">" << endl;
- t << " <info>" << endl;
- t << " <title>" << convertToDocBook(dbk_projectName) << "</title>" << endl;
- t << " </info>" << endl;
-
- // NAMESPACE DOCUMENTATION
- NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
- NamespaceDef *nd;
-
- //Namespace Documentation index header
- if (nli.toFirst())
- {
- t << " <chapter>" << endl;
- t << " <title>Namespace Documentation</title>" << endl;
- }
-
- for (nli.toFirst();(nd=nli.current());++nli)
- {
- msg("Generating Docbook output for namespace %s\n",nd->name().data());
- generateDocbookForNamespace(nd,t);
- }
-
- //Namespace Documentation index footer
- if (nli.toFirst())
- {
- t << " </chapter>" << endl;
- }
-
- /** MAINPAGE DOCUMENTATION **/
-
- if (Doxygen::mainPage)
- {
- msg("Generating Docbook output for the main page\n");
- generateDocbookForPage(Doxygen::mainPage,t,FALSE);
- }
-
- // PAGE DOCUMENTATION
- {
- PageSDict::Iterator pdi(*Doxygen::pageSDict);
- PageDef *pd=0;
-
- for (pdi.toFirst();(pd=pdi.current());++pdi)
- {
- msg("Generating Docbook output for page %s\n",pd->name().data());
- generateDocbookForPage(pd,t,FALSE);
- }
- }
-
- /** MODULE GROUP DOCUMENTATION **/
-
- GroupSDict::Iterator gli(*Doxygen::groupSDict);
- GroupDef *gd;
-
- //Module group Documentation index header
- if (gli.toFirst())
- {
- t << " <chapter>" << endl;
- t << " <title>" << theTranslator->trModuleDocumentation() << "</title>" << endl;
- }
-
- for (;(gd=gli.current());++gli)
- {
- msg("Generating Docbook output for group %s\n",gd->name().data());
- generateDocbookForGroup(gd,t);
- }
-
- //Module group Documentation index footer
- if (gli.toFirst())
- {
- t << " </chapter>" << endl;
- }
-
- //CLASS DOCUMENTATION
-
- {
- ClassSDict::Iterator cli(*Doxygen::classSDict);
- ClassDef *cd;
-
- //Class Documentation index header
- if (cli.toFirst())
- {
- t << " <chapter>" << endl;
- t << " <title>" << theTranslator->trClassDocumentation() << "</title>" << endl;
- }
-
- for (cli.toFirst();(cd=cli.current());++cli)
- {
- generateDocbookForClass(cd,t);
- }
-
- //Class Documentation index footer
- if (cli.toFirst())
- {
- t << " </chapter>" << endl;
- }
- }
-
- // FILE DOCUMENTATION
-
- static bool showFiles = Config_getBool(SHOW_FILES);
- if (showFiles)
- {
- FileNameListIterator fnli(*Doxygen::inputNameList);
- FileName *fn;
-
- //File Documentation index header
- if (fnli.toFirst())
- {
- t << " <chapter>" << endl;
- t << " <title>" << theTranslator->trFileDocumentation() << "</title>" << endl;
- }
-
- for (;(fn=fnli.current());++fnli)
- {
- FileNameIterator fni(*fn);
- FileDef *fd;
- for (;(fd=fni.current());++fni)
- {
- msg("Generating Docbook output for file %s\n",fd->name().data());
- generateDocbookForFile(fd,t);
- }
- }
-
- //File Documentation index footer
- if (fnli.toFirst())
- {
- t << " </chapter>" << endl;
- }
- }
-
- // DIRECTORY DOCUMENTATION
- if (Config_getBool(DIRECTORY_GRAPH) && Config_getBool(HAVE_DOT))
- {
- DirDef *dir;
- DirSDict::Iterator sdi(*Doxygen::directories);
-
- //Directory Documentation index header
- if (sdi.toFirst())
- {
- t << " <chapter>" << endl;
- t << " <title>" << theTranslator->trDirDocumentation() << "</title>" << endl;
- }
-
- for (sdi.toFirst();(dir=sdi.current());++sdi)
- {
- msg("Generate Docbook output for dir %s\n",dir->name().data());
- generateDocbookForDir(dir,t);
- }
-
- //Module group Documentation index footer
- if (sdi.toFirst())
- {
- t << " </chapter>" << endl;
- }
- }
-
- // EXAMPLE PAGE DOCUMENTATION
-
- {
- PageSDict::Iterator pdi(*Doxygen::exampleSDict);
- PageDef *pd=0;
-
- //Example Page Documentation index header
- if (pdi.toFirst())
- {
- t << " <chapter>" << endl;
- t << " <title>" << theTranslator->trExampleDocumentation() << "</title>" << endl;
- }
-
- for (pdi.toFirst();(pd=pdi.current());++pdi)
- {
- msg("Generating Docbook output for example %s\n",pd->name().data());
- generateDocbookForPage(pd,t,TRUE);
- }
-
- //Example Page Documentation index footer
- if (pdi.toFirst())
- {
- t << " </chapter>" << endl;
- }
- }
-
- t << "<index/>" << endl;
- t << "</book>" << endl;
-
-}
-
DocbookGenerator::DocbookGenerator() : OutputGenerator()
{
DB_GEN_C
diff --git a/src/docbookgen.h b/src/docbookgen.h
index 104fbc5..08255a1 100644
--- a/src/docbookgen.h
+++ b/src/docbookgen.h
@@ -17,8 +17,6 @@
#include "outputgen.h"
-void generateDocbook_v1();
-
class DocbookCodeGenerator : public CodeOutputInterface
{
public:
diff --git a/src/docbookvisitor.cpp b/src/docbookvisitor.cpp
index da84931..a5f0483 100644
--- a/src/docbookvisitor.cpp
+++ b/src/docbookvisitor.cpp
@@ -941,7 +941,8 @@ void DocbookDocVisitor::visitPost(DocHtmlTable *)
{
DB_VIS_C
if (m_hide) return;
- m_t << " </tbody>" << endl;
+ if (bodySet) m_t << " </tbody>" << endl;
+ bodySet = FALSE;
m_t << " </tgroup>" << endl;
m_t << "</informaltable>" << endl;
}
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 6057f1c..f01b509 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -56,6 +56,8 @@
#include "markdown.h"
#include "htmlentity.h"
+#define TK_COMMAND_CHAR(token) ((token)==TK_COMMAND_AT ? '@' : '\\')
+
// debug off
#define DBG(x) do {} while(0)
@@ -866,7 +868,31 @@ static bool findDocsForMemberOrCompound(const char *commandName,
return FALSE;
}
//---------------------------------------------------------------------------
+inline void errorHandleDefaultToken(DocNode *parent,int tok,
+ QList<DocNode> &children,const char *txt)
+{
+ switch (tok)
+ {
+ case TK_COMMAND_AT:
+ // fall through
+ case TK_COMMAND_BS:
+ children.append(new DocWord(parent,TK_COMMAND_CHAR(tok) + g_token->name));
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a %s",
+ qPrint(TK_COMMAND_CHAR(tok) + g_token->name), txt);
+ break;
+ case TK_SYMBOL:
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found found as part of a %s",
+ qPrint(g_token->name), txt);
+ break;
+ default:
+ children.append(new DocWord(parent,g_token->name));
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s found as part of a %s",
+ tokToString(tok), txt);
+ break;
+ }
+}
+//---------------------------------------------------------------------------
// forward declaration
static bool defaultHandleToken(DocNode *parent,int tok,
QList<DocNode> &children,bool
@@ -876,6 +902,7 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children,
const QCString &cmdName)
{
DBG(("handleStyleArgument(%s)\n",qPrint(cmdName)));
+ QCString saveCmdName = cmdName;
int tok=doctokenizerYYlex();
if (tok!=TK_WHITESPACE)
{
@@ -901,14 +928,6 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children,
{
switch (tok)
{
- case TK_COMMAND:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command \\%s as the argument of a \\%s command",
- qPrint(g_token->name),qPrint(cmdName));
- break;
- case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found while handling command %s",
- qPrint(g_token->name),qPrint(cmdName));
- break;
case TK_HTMLTAG:
if (insideLI(parent) && Mappers::htmlTagMapper->map(g_token->name) && g_token->endTag)
{ // ignore </li> as the end of a style command
@@ -917,8 +936,7 @@ static int handleStyleArgument(DocNode *parent,QList<DocNode> &children,
return tok;
break;
default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s while handling command %s",
- tokToString(tok),qPrint(cmdName));
+ errorHandleDefaultToken(parent,tok,children,"\\" + saveCmdName + " command");
break;
}
break;
@@ -1297,21 +1315,7 @@ static void defaultHandleTitleAndSize(const int cmd, DocNode *parent, QList<DocN
}
if (!defaultHandleToken(parent,tok,children))
{
- switch (tok)
- {
- case TK_COMMAND:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\%s",
- qPrint(g_token->name), Mappers::cmdMapper->find(cmd).data());
- break;
- case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
- qPrint(g_token->name));
- break;
- default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
- tokToString(tok));
- break;
- }
+ errorHandleDefaultToken(parent,tok,children,Mappers::cmdMapper->find(cmd).data());
}
}
// parse size attributes
@@ -1370,7 +1374,7 @@ static bool defaultHandleToken(DocNode *parent,int tok, QList<DocNode> &children
{
DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno));
if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL ||
- tok==TK_COMMAND || tok==TK_HTMLTAG
+ tok==TK_COMMAND_AT || tok==TK_COMMAND_BS || tok==TK_HTMLTAG
)
{
DBG((" name=%s",qPrint(g_token->name)));
@@ -1380,7 +1384,9 @@ reparsetoken:
QCString tokenName = g_token->name;
switch (tok)
{
- case TK_COMMAND:
+ case TK_COMMAND_AT:
+ // fall through
+ case TK_COMMAND_BS:
switch (Mappers::cmdMapper->map(tokenName))
{
case CMD_BSLASH:
@@ -1564,6 +1570,9 @@ reparsetoken:
doctokenizerYYsetStatePara();
}
break;
+ case CMD_IMAGE:
+ ((DocPara *)parent) -> handleImage("image");
+ break;
default:
return FALSE;
}
@@ -1901,11 +1910,8 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor)
{
warn_doc_error(g_fileName,doctokenizerYYlineno,"Empty anchor label");
}
- if (newAnchor) // found <a name="label">
- {
- m_anchor = id;
- }
- else if (id.left(CiteConsts::anchorPrefix.length()) == CiteConsts::anchorPrefix)
+
+ if (id.left(CiteConsts::anchorPrefix.length()) == CiteConsts::anchorPrefix)
{
CiteInfo *cite = Doxygen::citeDict->find(id.mid(CiteConsts::anchorPrefix.length()));
if (cite)
@@ -1920,6 +1926,10 @@ DocAnchor::DocAnchor(DocNode *parent,const QCString &id,bool newAnchor)
m_file = "invalid";
}
}
+ else if (newAnchor) // found <a name="label">
+ {
+ m_anchor = id;
+ }
else // found \anchor label
{
SectionInfo *sec = Doxygen::sectionDict->find(id);
@@ -2331,21 +2341,7 @@ void DocSecRefItem::parse()
{
if (!defaultHandleToken(this,tok,m_children))
{
- switch (tok)
- {
- case TK_COMMAND:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\refitem",
- qPrint(g_token->name));
- break;
- case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
- qPrint(g_token->name));
- break;
- default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
- tokToString(tok));
- break;
- }
+ errorHandleDefaultToken(this,tok,m_children,"\\refitem");
}
}
doctokenizerYYsetStatePara();
@@ -2393,7 +2389,7 @@ void DocSecRefList::parse()
// handle items
while (tok)
{
- if (tok==TK_COMMAND)
+ if (tok==TK_COMMAND_AT || tok == TK_COMMAND_BS)
{
switch (Mappers::cmdMapper->map(g_token->name))
{
@@ -2473,21 +2469,7 @@ void DocInternalRef::parse()
{
if (!defaultHandleToken(this,tok,m_children))
{
- switch (tok)
- {
- case TK_COMMAND:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\ref",
- qPrint(g_token->name));
- break;
- case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
- qPrint(g_token->name));
- break;
- default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
- tokToString(tok));
- break;
- }
+ errorHandleDefaultToken(this,tok,m_children,"\\ref");
}
}
@@ -2631,19 +2613,10 @@ void DocRef::parse()
{
switch (tok)
{
- case TK_COMMAND:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\ref",
- qPrint(g_token->name));
- break;
- case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
- qPrint(g_token->name));
- break;
case TK_HTMLTAG:
break;
default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
- tokToString(tok));
+ errorHandleDefaultToken(this,tok,m_children,"\\ref");
break;
}
}
@@ -2754,7 +2727,9 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink)
{
switch (tok)
{
- case TK_COMMAND:
+ case TK_COMMAND_AT:
+ // fall through
+ case TK_COMMAND_BS:
switch (Mappers::cmdMapper->map(g_token->name))
{
case CMD_ENDLINK:
@@ -2770,13 +2745,13 @@ QCString DocLink::parse(bool isJavaLink,bool isXmlLink)
}
break;
case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found as part of a \\link",
qPrint(g_token->name));
break;
case TK_HTMLTAG:
if (g_token->name!="see" || !isXmlLink)
{
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected xml/html command %s found",
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected xml/html command %s found as part of a \\link",
qPrint(g_token->name));
}
goto endlink;
@@ -2954,21 +2929,7 @@ void DocVhdlFlow::parse()
{
if (!defaultHandleToken(this,tok,m_children))
{
- switch (tok)
- {
- case TK_COMMAND:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a \\vhdlflow",
- qPrint(g_token->name));
- break;
- case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
- qPrint(g_token->name));
- break;
- default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
- tokToString(tok));
- break;
- }
+ errorHandleDefaultToken(this,tok,m_children,"\\vhdlflow");
}
}
tok=doctokenizerYYlex();
@@ -3015,10 +2976,6 @@ int DocHtmlHeader::parse()
{
switch (tok)
{
- case TK_COMMAND:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <h%d> tag",
- qPrint(g_token->name),m_level);
- break;
case TK_HTMLTAG:
{
int tagId=Mappers::htmlTagMapper->map(g_token->name);
@@ -3096,14 +3053,10 @@ int DocHtmlHeader::parse()
}
break;
- case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
- qPrint(g_token->name));
- break;
default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
- tokToString(tok));
- break;
+ char tmp[20];
+ sprintf(tmp,"<h%d>tag",m_level);
+ errorHandleDefaultToken(this,tok,m_children,tmp);
}
}
}
@@ -3135,14 +3088,6 @@ int DocHRef::parse()
{
switch (tok)
{
- case TK_COMMAND:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <a>..</a> block",
- qPrint(g_token->name));
- break;
- case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
- qPrint(g_token->name));
- break;
case TK_HTMLTAG:
{
@@ -3159,8 +3104,7 @@ int DocHRef::parse()
}
break;
default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
- tokToString(tok),doctokenizerYYlineno);
+ errorHandleDefaultToken(this,tok,m_children,"<a>..</a> block");
break;
}
}
@@ -3293,7 +3237,9 @@ int DocIndexEntry::parse()
}
}
break;
- case TK_COMMAND:
+ case TK_COMMAND_AT:
+ // fall through
+ case TK_COMMAND_BS:
switch (Mappers::cmdMapper->map(g_token->name))
{
case CMD_BSLASH: m_entry+='\\'; break;
@@ -3381,14 +3327,6 @@ int DocHtmlCaption::parse()
{
switch (tok)
{
- case TK_COMMAND:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <caption> tag",
- qPrint(g_token->name));
- break;
- case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
- qPrint(g_token->name));
- break;
case TK_HTMLTAG:
{
int tagId=Mappers::htmlTagMapper->map(g_token->name);
@@ -3405,9 +3343,7 @@ int DocHtmlCaption::parse()
}
break;
default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
- tokToString(tok));
- break;
+ errorHandleDefaultToken(this,tok,m_children,"<caption> tag");
}
}
}
@@ -3920,7 +3856,9 @@ int DocHtmlDescTitle::parse()
{
switch (tok)
{
- case TK_COMMAND:
+ case TK_COMMAND_AT:
+ // fall through
+ case TK_COMMAND_BS:
{
QCString cmdName=g_token->name;
bool isJavaLink=FALSE;
@@ -3931,7 +3869,7 @@ int DocHtmlDescTitle::parse()
int tok=doctokenizerYYlex();
if (tok!=TK_WHITESPACE)
{
- warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command",
qPrint(g_token->name));
}
else
@@ -3940,7 +3878,7 @@ int DocHtmlDescTitle::parse()
tok=doctokenizerYYlex(); // get the reference id
if (tok!=TK_WORD)
{
- warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of \\%s command",
tokToString(tok),qPrint(cmdName));
}
else
@@ -3961,7 +3899,7 @@ int DocHtmlDescTitle::parse()
int tok=doctokenizerYYlex();
if (tok!=TK_WHITESPACE)
{
- warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after %s command",
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"expected whitespace after \\%s command",
qPrint(cmdName));
}
else
@@ -3970,7 +3908,7 @@ int DocHtmlDescTitle::parse()
tok=doctokenizerYYlex();
if (tok!=TK_WORD)
{
- warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of %s",
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"unexpected token %s as the argument of \\%s command",
tokToString(tok),qPrint(cmdName));
}
else
@@ -3989,13 +3927,13 @@ int DocHtmlDescTitle::parse()
break;
default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a <dt> tag",
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command \\%s found as part of a <dt> tag",
qPrint(g_token->name));
}
}
break;
case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol \\%s found as part of a <dt> tag",
qPrint(g_token->name));
break;
case TK_HTMLTAG:
@@ -4036,7 +3974,7 @@ int DocHtmlDescTitle::parse()
}
break;
default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
+ warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s found as part of a <dt> tag",
tokToString(tok));
break;
}
@@ -4541,21 +4479,7 @@ void DocTitle::parse()
{
if (!defaultHandleToken(this,tok,m_children))
{
- switch (tok)
- {
- case TK_COMMAND:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Illegal command %s as part of a title section",
- qPrint(g_token->name));
- break;
- case TK_SYMBOL:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unsupported symbol %s found",
- qPrint(g_token->name));
- break;
- default:
- warn_doc_error(g_fileName,doctokenizerYYlineno,"Unexpected token %s",
- tokToString(tok));
- break;
- }
+ errorHandleDefaultToken(this,tok,m_children,"title section");
}
}
doctokenizerYYsetStatePara();
@@ -5416,7 +5340,7 @@ void DocPara::handleInheritDoc()
}
-int DocPara::handleCommand(const QCString &cmdName)
+int DocPara::handleCommand(const QCString &cmdName, const int tok)
{
DBG(("handleCommand(%s)\n",qPrint(cmdName)));
int retval = RetVal_OK;
@@ -5424,6 +5348,7 @@ int DocPara::handleCommand(const QCString &cmdName)
switch (cmdId)
{
case CMD_UNKNOWN:
+ m_children.append(new DocWord(this,TK_COMMAND_CHAR(tok) + cmdName));
warn_doc_error(g_fileName,doctokenizerYYlineno,"Found unknown command `\\%s'",qPrint(cmdName));
break;
case CMD_EMPHASIS:
@@ -6526,7 +6451,7 @@ int DocPara::parse()
reparsetoken:
DBG(("token %s at %d",tokToString(tok),doctokenizerYYlineno));
if (tok==TK_WORD || tok==TK_LNKWORD || tok==TK_SYMBOL || tok==TK_URL ||
- tok==TK_COMMAND || tok==TK_HTMLTAG
+ tok==TK_COMMAND_AT || tok == TK_COMMAND_BS || tok==TK_HTMLTAG
)
{
DBG((" name=%s",qPrint(g_token->name)));
@@ -6624,7 +6549,7 @@ reparsetoken:
}
else // other section
{
- tok = TK_COMMAND;
+ tok = TK_COMMAND_BS;
}
DBG(("reparsing command %s\n",qPrint(g_token->name)));
goto reparsetoken;
@@ -6669,7 +6594,9 @@ reparsetoken:
"list items");
}
break;
- case TK_COMMAND:
+ case TK_COMMAND_AT:
+ // fall through
+ case TK_COMMAND_BS:
{
// see if we have to start a simple section
int cmd = Mappers::cmdMapper->map(g_token->name);
@@ -6705,7 +6632,7 @@ reparsetoken:
}
// handle the command
- retval=handleCommand(g_token->name);
+ retval=handleCommand(g_token->name,tok);
DBG(("handleCommand returns %x\n",retval));
// check the return value
@@ -6723,7 +6650,7 @@ reparsetoken:
}
else // other section
{
- tok = TK_COMMAND;
+ tok = TK_COMMAND_BS;
}
DBG(("reparsing command %s\n",qPrint(g_token->name)));
goto reparsetoken;
@@ -6995,7 +6922,9 @@ void DocText::parse()
}
}
break;
- case TK_COMMAND:
+ case TK_COMMAND_AT:
+ // fall through
+ case TK_COMMAND_BS:
switch (Mappers::cmdMapper->map(g_token->name))
{
case CMD_BSLASH:
diff --git a/src/docparser.h b/src/docparser.h
index 68f9fc1..2bc716a 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -1155,7 +1155,7 @@ class DocPara : public CompAccept<DocPara>
bool isFirst() const { return m_isFirst; }
bool isLast() const { return m_isLast; }
- int handleCommand(const QCString &cmdName);
+ int handleCommand(const QCString &cmdName,const int tok);
int handleHtmlStartTag(const QCString &tagName,const HtmlAttribList &tagHtmlAttribs);
int handleHtmlEndTag(const QCString &tagName);
int handleSimpleSection(DocSimpleSect::Type t,bool xmlContext=FALSE);
diff --git a/src/doctokenizer.h b/src/doctokenizer.h
index b3b9fa5..c12e77e 100644
--- a/src/doctokenizer.h
+++ b/src/doctokenizer.h
@@ -34,12 +34,13 @@ enum Tokens
TK_WHITESPACE = 3,
TK_LISTITEM = 4,
TK_ENDLIST = 5,
- TK_COMMAND = 6,
+ TK_COMMAND_AT = 6, //! Command starting with `@`
TK_HTMLTAG = 7,
TK_SYMBOL = 8,
TK_NEWPARA = 9,
TK_RCSTAG = 10,
TK_URL = 11,
+ TK_COMMAND_BS = 12, //! Command starting with `\`
RetVal_OK = 0x10000,
RetVal_SimpleSec = 0x10001,
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 3118cfd..6a703df 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -41,6 +41,8 @@
#define YY_NO_INPUT 1
#define YY_NO_UNISTD_H 1
+
+#define TK_COMMAND_SEL() (yytext[0] == '@' ? TK_COMMAND_AT : TK_COMMAND_BS)
//--------------------------------------------------------------------------
@@ -116,12 +118,13 @@ const char *tokToString(int token)
case TK_WHITESPACE: return "TK_WHITESPACE";
case TK_LISTITEM: return "TK_LISTITEM";
case TK_ENDLIST: return "TK_ENDLIST";
- case TK_COMMAND: return "TK_COMMAND";
+ case TK_COMMAND_AT: return "TK_COMMAND_AT";
case TK_HTMLTAG: return "TK_HTMLTAG";
case TK_SYMBOL: return "TK_SYMBOL";
case TK_NEWPARA: return "TK_NEWPARA";
case TK_RCSTAG: return "TK_RCSTAG";
case TK_URL: return "TK_URL";
+ case TK_COMMAND_BS: return "TK_COMMAND_BS";
}
return "ERROR";
}
@@ -403,8 +406,8 @@ REFWORD2_NOCV {REFWORD2_PRE}("("{FUNCPART}")")?
REFWORD3 ({ID}":")*{ID}":"?
REFWORD4_NOCV (({SCOPEPRE}*"operator"{OPMASKOP2})|(("::"|"#"){SCOPEPRE}*"operator"{OPMASKOP2}))
REFWORD4 {REFWORD4_NOCV}{CVSPEC}?
-REFWORD {LABELID}|{REFWORD2}|{REFWORD3}|{REFWORD4}
-REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
+REFWORD {FILEMASK}|{LABELID}|{REFWORD2}|{REFWORD3}|{REFWORD4}
+REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
%option noyywrap
%option yylineno
@@ -558,11 +561,11 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
}
<St_Para>"{"{BLANK}*"@link"/{BLANK}+ {
g_token->name = "javalink";
- return TK_COMMAND;
+ return TK_COMMAND_AT;
}
<St_Para>"{"{BLANK}*"@inheritDoc"{BLANK}*"}" {
g_token->name = "inheritdoc";
- return TK_COMMAND;
+ return TK_COMMAND_AT;
}
<St_Para>"@_fakenl" { // artificial new line
yylineno++;
@@ -572,14 +575,14 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
bool ok;
g_token->id = QCString(yytext).right((int)yyleng-6).toInt(&ok);
ASSERT(ok);
- return TK_COMMAND;
+ return TK_COMMAND_SEL();
}
<St_Para>{CMD}"n"\n { /* \n followed by real newline */
yylineno++;
g_token->name = yytext+1;
g_token->name = g_token->name.stripWhiteSpace();
g_token->paramDir=TokenInfo::Unspecified;
- return TK_COMMAND;
+ return TK_COMMAND_SEL();
}
<St_Para>{SPCMD1} |
<St_Para>{SPCMD2} |
@@ -587,7 +590,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
g_token->name = yytext+1;
g_token->name = g_token->name.stripWhiteSpace();
g_token->paramDir=TokenInfo::Unspecified;
- return TK_COMMAND;
+ return TK_COMMAND_SEL();
}
<St_Para>{PARAMIO} { /* param [in,out] command */
g_token->name = "param";
@@ -613,7 +616,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
{
g_token->paramDir=TokenInfo::Unspecified;
}
- return TK_COMMAND;
+ return TK_COMMAND_SEL();
}
<St_Para>("http:"|"https:"|"ftp:"|"file:"|"news:"){URLMASK}/\. { // URL.
g_token->name=yytext;
@@ -733,7 +736,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
}
<St_Text>[\\@<>&$#%~] {
g_token->name = yytext;
- return TK_COMMAND;
+ return TK_COMMAND_SEL();
}
<St_Para>({BLANK}*\n)+{BLANK}*\n/{LISTITEM} { /* skip trailing paragraph followed by new list item */
if (g_insidePre || g_autoListLevel==0)
@@ -926,7 +929,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
<St_TitleN>{SPCMD2} { /* special command */
g_token->name = yytext+1;
g_token->paramDir=TokenInfo::Unspecified;
- return TK_COMMAND;
+ return TK_COMMAND_SEL();
}
<St_TitleN>{ID}"=" { /* attribute */
if (yytext[0]=='%') // strip % if present
@@ -960,7 +963,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
<St_TitleQ>{SPCMD2} { /* special command */
g_token->name = yytext+1;
g_token->paramDir=TokenInfo::Unspecified;
- return TK_COMMAND;
+ return TK_COMMAND_SEL();
}
<St_TitleQ>{WORD1NQ} |
<St_TitleQ>{WORD2NQ} { /* word */
@@ -1091,7 +1094,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
<St_Ref2>{SPCMD2} { /* special command */
g_token->name = yytext+1;
g_token->paramDir=TokenInfo::Unspecified;
- return TK_COMMAND;
+ return TK_COMMAND_SEL();
}
<St_Ref2>{WORD1NQ} |
<St_Ref2>{WORD2NQ} {
@@ -1323,7 +1326,7 @@ REFWORD_NOCV {LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
<*>[\\@<>&$#%~"=] { /* unescaped special character */
//warn(g_fileName,yylineno,"Unexpected character `%s', assuming command \\%s was meant.",yytext,yytext);
g_token->name = yytext;
- return TK_COMMAND;
+ return TK_COMMAND_SEL();
}
<*>. {
warn(g_fileName,yylineno,"Unexpected character `%s'",yytext);
diff --git a/src/dot.cpp b/src/dot.cpp
index 5f52210..f07a365 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -139,7 +139,7 @@ static const char svgZoomFooter[] =
" <path fill=\"none\" stroke=\"white\" stroke-width=\"1.5\" d=\"M0,-3.0v7 M-2.5,-0.5L0,-3.0L2.5,-0.5\"/>\n"
" </g>\n"
" </g>\n"
-// link to orginial SVG
+// link to original SVG
" <svg viewBox=\"0 0 15 15\" width=\"100%\" height=\"30px\" preserveAspectRatio=\"xMaxYMin meet\">\n"
" <g id=\"arrow_out\" transform=\"scale(0.3 0.3)\">\n"
" <a xlink:href=\"$orgname\" target=\"_base\">\n"
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 58c7019..511795f 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -347,6 +347,7 @@ static STLInfo g_stlinfo[] =
{ "auto_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // deprecated
{ "smart_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
{ "unique_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
+ { "shared_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++14
{ "weak_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
{ "ios_base", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
{ "error_code", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
@@ -520,7 +521,7 @@ static void addSTLClasses(EntryNav *rootNav)
{
addSTLMember(classEntryNav,info->templType2,info->templName2);
}
- if (fullName=="std::auto_ptr" || fullName=="std::smart_ptr" ||
+ if (fullName=="std::auto_ptr" || fullName=="std::smart_ptr" || fullName=="std::shared_ptr" ||
fullName=="std::unique_ptr" || fullName=="std::weak_ptr")
{
Entry *memEntry = new Entry;
@@ -7730,7 +7731,7 @@ static void computeMemberRelations()
// bmcd->name().data(),bmd->name().data(),bmd
// );
if (md!=bmd && bmcd && mcd && bmcd!=mcd &&
- (bmd->virtualness()!=Normal ||
+ (bmd->virtualness()!=Normal || bmd->getLanguage()==SrcLangExt_Python ||
bmcd->compoundType()==ClassDef::Interface ||
bmcd->compoundType()==ClassDef::Protocol
) &&
@@ -9684,7 +9685,7 @@ int readDir(QFileInfo *fi,
{
fn = new FileName(cfi->absFilePath().utf8(),name);
fn->append(fd);
- if (fnList) fnList->inSort(fn);
+ if (fnList) fnList->append(fn);
fnDict->insert(name,fn);
}
}
@@ -9783,7 +9784,7 @@ int readFileOrDirectory(const char *s,
{
fn = new FileName(filePath,name);
fn->append(fd);
- if (fnList) fnList->inSort(fn);
+ if (fnList) fnList->append(fn);
fnDict->insert(name,fn);
}
}
@@ -9922,7 +9923,7 @@ static void escapeAliases()
while ((in=value.find("^^",p))!=-1)
{
newValue+=value.mid(p,in-p);
- newValue+="\\_linebr";
+ newValue+="@_linebr";
p=in+2;
}
newValue+=value.mid(p,value.length()-p);
@@ -10996,6 +10997,7 @@ void searchInputFiles()
}
s=inputList.next();
}
+ Doxygen::inputNameList->sort();
delete killDict;
g_s.end();
}
@@ -11565,13 +11567,11 @@ void generateOutput()
g_outputList->add(new LatexGenerator);
LatexGenerator::init();
}
-#if 1
if (generateDocbook)
{
g_outputList->add(new DocbookGenerator);
DocbookGenerator::init();
}
-#endif
if (generateMan)
{
g_outputList->add(new ManGenerator);
@@ -11750,15 +11750,6 @@ void generateOutput()
g_s.end();
}
-#if 0
- if (generateDocbook)
- {
- g_s.begin("Generating Docbook output...\n");
- generateDocbook_v1();
- g_s.end();
- }
-#endif
-
if (Config_getBool(GENERATE_AUTOGEN_DEF))
{
g_s.begin("Generating AutoGen DEF output...\n");
diff --git a/src/fortrancode.l b/src/fortrancode.l
index 3014dc3..0e610fd 100644
--- a/src/fortrancode.l
+++ b/src/fortrancode.l
@@ -107,8 +107,9 @@ class Scope
public:
QCStringList useNames; //!< contains names of used modules
QDict<void> localVars; //!< contains names of local variables
+ QDict<void> externalVars; //!< contains names of external entities
- Scope() : localVars(7, FALSE /*caseSensitive*/) {}
+ Scope() : localVars(7, FALSE /*caseSensitive*/), externalVars(7, FALSE /*caseSensitive*/) {}
};
/*===================================================================*/
@@ -122,6 +123,7 @@ static QCString currentClass=0; //!< name of the current enclosing
static UseSDict *useMembers= new UseSDict; //!< info about used modules
static UseEntry *useEntry = 0; //!< current use statement info
static QList<Scope> scopeStack;
+static bool g_isExternal = false;
// static QCStringList *currentUseNames= new QCStringList; //! contains names of used modules of current program unit
static QCString str=""; //!> contents of fortran string
@@ -434,7 +436,7 @@ static bool getFortranDefs(const QCString &memberName, const QCString &moduleNam
Scope *scope;
for (it.toLast();(scope=it.current());--it)
{
- if (scope->localVars.find(memberName))
+ if (scope->localVars.find(memberName) && (!scope->externalVars.find(memberName)))
return FALSE;
}
@@ -648,7 +650,10 @@ static void addUse(const QCString &moduleName)
static void addLocalVar(const QCString &varName)
{
if (!scopeStack.isEmpty())
+ {
scopeStack.getLast()->localVars.insert(varName, (void*)1);
+ if (g_isExternal) scopeStack.getLast()->externalVars.insert(varName, (void*)1);
+ }
}
//----------------------------------------------------------------------------
@@ -969,11 +974,18 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?")
endFontClass();
}
<Start>{ATTR_SPEC} {
+ if (QCString(yytext) == "external")
+ {
+ yy_push_state(YY_START);
+ BEGIN(Declaration);
+ g_isExternal = true;
+ }
startFontClass("keywordtype");
g_code->codify(yytext);
endFontClass();
}
<Declaration>({TYPE_SPEC}|{ATTR_SPEC})/[,:( ] { //| variable declaration
+ if (QCString(yytext) == "external") g_isExternal = true;
startFontClass("keywordtype");
g_code->codify(yytext);
endFontClass();
@@ -1046,6 +1058,7 @@ LANGUAGE_BIND_SPEC BIND{BS}"("{BS}C{BS}(,{BS}NAME{BS}"="{BS}"\""(.*)"\""{BS})?")
g_contLineNr++;
if (!(g_hasContLine && g_hasContLine[g_contLineNr - 1]))
{
+ g_isExternal = false;
yy_pop_state();
}
YY_FTN_RESET
diff --git a/src/fortranscanner.l b/src/fortranscanner.l
index 2bd6788..5f10669 100644
--- a/src/fortranscanner.l
+++ b/src/fortranscanner.l
@@ -231,6 +231,8 @@ static void updateVariablePrepassComment(int from, int to);
static void newLine();
static void initEntry();
+static const char *stateToString(int state);
+
//-----------------------------------------------------------------------------
#undef YY_INPUT
#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
@@ -2759,7 +2761,7 @@ void FortranLanguageScanner::parsePrototype(const char *text)
static void scanner_abort()
{
fprintf(stderr,"********************************************************************\n");
- fprintf(stderr,"Error in file %s line: %d, state: %d\n",yyFileName.data(),yyLineNr,YY_START);
+ fprintf(stderr,"Error in file %s line: %d, state: %d(%s)\n",yyFileName.data(),yyLineNr,YY_START,stateToString(YY_START));
fprintf(stderr,"********************************************************************\n");
EntryListIterator eli(*global_root->children());
@@ -2788,3 +2790,47 @@ extern "C" { // some bogus code to keep the compiler happy
}
#endif
+#define scanStateToString(x) case x: resultString = #x; break;
+static const char *stateToString(int state)
+{
+ const char *resultString;
+ switch(state)
+ {
+ scanStateToString(INITIAL)
+ scanStateToString(Subprog)
+ scanStateToString(SubprogPrefix)
+ scanStateToString(Parameterlist)
+ scanStateToString(SubprogBody)
+ scanStateToString(SubprogBodyContains)
+ scanStateToString(Start)
+ scanStateToString(Comment)
+ scanStateToString(Module)
+ scanStateToString(Program)
+ scanStateToString(ModuleBody)
+ scanStateToString(ModuleBodyContains)
+ scanStateToString(AttributeList)
+ scanStateToString(Variable)
+ scanStateToString(Initialization)
+ scanStateToString(ArrayInitializer)
+ scanStateToString(Enum)
+ scanStateToString(Typedef)
+ scanStateToString(TypedefBody)
+ scanStateToString(TypedefBodyContains)
+ scanStateToString(InterfaceBody)
+ scanStateToString(StrIgnore)
+ scanStateToString(String)
+ scanStateToString(Use)
+ scanStateToString(UseOnly)
+ scanStateToString(ModuleProcedure)
+ scanStateToString(Prepass)
+ scanStateToString(DocBlock)
+ scanStateToString(DocBackLine)
+ scanStateToString(EndDoc)
+ scanStateToString(BlockData)
+ scanStateToString(Prototype)
+ scanStateToString(PrototypeSubprog)
+ scanStateToString(PrototypeArgs)
+ default: resultString = "Unknown"; break;
+ }
+ return resultString;
+}
diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp
index 452a481..56691cf 100644
--- a/src/latexdocvisitor.cpp
+++ b/src/latexdocvisitor.cpp
@@ -215,13 +215,14 @@ void LatexDocVisitor::visit(DocURL *u)
if (m_hide) return;
if (Config_getBool(PDF_HYPERLINKS))
{
+ m_t << endl << "%% AME " << u->url() <<endl;
m_t << "\\href{";
if (u->isEmail()) m_t << "mailto:";
- m_t << u->url() << "}";
+ m_t << latexFilterURL(u->url()) << "}";
}
- m_t << "\\texttt{ ";
+ m_t << "{\\texttt{ ";
filter(u->url());
- m_t << "}";
+ m_t << "}}";
}
void LatexDocVisitor::visit(DocLineBreak *)
@@ -564,9 +565,9 @@ void LatexDocVisitor::visit(DocIndexEntry *i)
{
if (m_hide) return;
m_t << "\\index{";
- m_t << latexEscapeLabelName(i->entry(),false);
+ m_t << latexEscapeLabelName(i->entry());
m_t << "@{";
- m_t << latexEscapeIndexChars(i->entry(),false);
+ m_t << latexEscapeIndexChars(i->entry());
m_t << "}}";
}
@@ -1251,17 +1252,18 @@ void LatexDocVisitor::visitPre(DocHRef *href)
if (m_hide) return;
if (Config_getBool(PDF_HYPERLINKS))
{
+ m_t << endl << "%% AME " << href->url() <<endl;
m_t << "\\href{";
- m_t << href->url();
+ m_t << latexFilterURL(href->url());
m_t << "}";
}
- m_t << "\\texttt{ ";
+ m_t << "{\\texttt{ ";
}
void LatexDocVisitor::visitPost(DocHRef *)
{
if (m_hide) return;
- m_t << "}";
+ m_t << "}}";
}
void LatexDocVisitor::visitPre(DocHtmlHeader *header)
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index 50d4242..d061dd7 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -1369,12 +1369,12 @@ void LatexGenerator::startHtmlLink(const char *url)
t << url;
t << "}";
}
- t << "\\texttt{ ";
+ t << "{\\texttt{ ";
}
void LatexGenerator::endHtmlLink()
{
- t << "}";
+ t << "}}";
}
//void LatexGenerator::writeMailLink(const char *url)
@@ -1519,9 +1519,9 @@ void LatexGenerator::endTitleHead(const char *fileName,const char *name)
if (name)
{
t << "\\label{" << stripPath(fileName) << "}\\index{";
- t << latexEscapeLabelName(name,insideTabbing);
+ t << latexEscapeLabelName(name);
t << "@{";
- t << latexEscapeIndexChars(name,insideTabbing);
+ t << latexEscapeIndexChars(name);
t << "}}" << endl;
}
}
@@ -1602,27 +1602,27 @@ void LatexGenerator::startMemberDoc(const char *clname,
t << "\\index{";
if (clname)
{
- t << latexEscapeLabelName(clname,insideTabbing);
+ t << latexEscapeLabelName(clname);
t << "@{";
- t << latexEscapeIndexChars(clname,insideTabbing);
+ t << latexEscapeIndexChars(clname);
t << "}!";
}
- t << latexEscapeLabelName(memname,insideTabbing);
+ t << latexEscapeLabelName(memname);
t << "@{";
- t << latexEscapeIndexChars(memname,insideTabbing);
+ t << latexEscapeIndexChars(memname);
t << "}}" << endl;
t << "\\index{";
- t << latexEscapeLabelName(memname,insideTabbing);
+ t << latexEscapeLabelName(memname);
t << "@{";
- t << latexEscapeIndexChars(memname,insideTabbing);
+ t << latexEscapeIndexChars(memname);
t << "}";
if (clname)
{
t << "!";
- t << latexEscapeLabelName(clname,insideTabbing);
+ t << latexEscapeLabelName(clname);
t << "@{";
- t << latexEscapeIndexChars(clname,insideTabbing);
+ t << latexEscapeIndexChars(clname);
t << "}";
}
t << "}" << endl;
@@ -1640,7 +1640,7 @@ void LatexGenerator::startMemberDoc(const char *clname,
{
t << "\\texorpdfstring{";
}
- t << latexEscapeIndexChars(title,insideTabbing);
+ t << latexEscapeIndexChars(title);
if (pdfHyperlinks)
{
t << "}{" << latexEscapePDFString(title) << "}";
@@ -1715,16 +1715,16 @@ void LatexGenerator::addIndexItem(const char *s1,const char *s2)
if (s1)
{
t << "\\index{";
- t << latexEscapeLabelName(s1,insideTabbing);
+ t << latexEscapeLabelName(s1);
t << "@{";
- t << latexEscapeIndexChars(s1,insideTabbing);
+ t << latexEscapeIndexChars(s1);
t << "}";
if (s2)
{
t << "!";
- t << latexEscapeLabelName(s2,insideTabbing);
+ t << latexEscapeLabelName(s2);
t << "@{";
- t << latexEscapeIndexChars(s2,insideTabbing);
+ t << latexEscapeIndexChars(s2);
t << "}";
}
t << "}";
diff --git a/src/markdown.cpp b/src/markdown.cpp
index 59ce108..36b9734 100644
--- a/src/markdown.cpp
+++ b/src/markdown.cpp
@@ -1960,7 +1960,7 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size)
out.addStr(data,size);
if (hasLineBreak(data,size))
{
- out.addStr("<br>");
+ out.addStr("\n");
}
}
}
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index eb90cd1..8f57802 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -2564,7 +2564,7 @@ void MemberDef::writeDocumentation(MemberList *ml,
QCString scopeName = scName;
QCString memAnchor = anchor();
- QCString ciname = container->name();
+ QCString ciname = container->displayName();
Definition *scopedContainer = container; // see bug 753608
if (container->definitionType()==TypeGroup)
{
diff --git a/src/printdocvisitor.h b/src/printdocvisitor.h
index 8d9a2b9..6b5e09e 100644
--- a/src/printdocvisitor.h
+++ b/src/printdocvisitor.h
@@ -640,13 +640,13 @@ class PrintDocVisitor : public DocVisitor
void visitPre(DocXRefItem *x)
{
indent_pre();
- printf("<xrefitem file=\"%s\" anchor=\"%s\" title=\"%s\"/>\n",
+ printf("<xrefitem file=\"%s\" anchor=\"%s\" title=\"%s\">\n",
x->file().data(),x->anchor().data(),x->title().data());
}
void visitPost(DocXRefItem *)
{
indent_post();
- printf("<xrefitem/>\n");
+ printf("</xrefitem>\n");
}
void visitPre(DocInternalRef *r)
{
diff --git a/src/pyscanner.l b/src/pyscanner.l
index 3743712..aed1ede 100644
--- a/src/pyscanner.l
+++ b/src/pyscanner.l
@@ -119,6 +119,7 @@ static bool g_start_init = FALSE;
static int g_search_count = 0;
static QCString g_argType = "";
+static bool g_funcParamsEnd;
//-----------------------------------------------------------------------------
@@ -514,6 +515,8 @@ STARTDOCSYMS "##"
%x FunctionDec
%x FunctionParams
%x FunctionBody
+%x FunctionAnnotation
+%x FunctionTypeAnnotation
%x FunctionParamDefVal
/* Class states */
@@ -933,7 +936,6 @@ STARTDOCSYMS "##"
}
<FunctionDec>{
-
{IDENTIFIER} {
//found function name
if (current->type.isEmpty())
@@ -944,16 +946,26 @@ STARTDOCSYMS "##"
current->name = current->name.stripWhiteSpace();
newFunction();
}
- {B}":" { // function without arguments
+ {B}":"{B} { // function without arguments
g_specialBlock = TRUE; // expecting a docstring
bodyEntry = current;
current->bodyLine = yyLineNr;
- BEGIN( FunctionBody );
+ BEGIN(FunctionBody);
}
+ "->" {
+ g_defVal.resize(0);
+ g_braceCount = 0;
+ BEGIN(FunctionTypeAnnotation);
+ }
{B}"(" {
- BEGIN( FunctionParams );
+ g_funcParamsEnd = FALSE;
+ BEGIN(FunctionParams);
}
+ ")" { // end of parameter list
+ current->args = argListToString(current->argList);
+ g_funcParamsEnd = TRUE;
+ }
}
<FunctionParams>{
@@ -975,20 +987,18 @@ STARTDOCSYMS "##"
// TODO: this rule is too simple, need to be able to
// match things like =")" as well!
g_defVal.resize(0);
- g_braceCount=0;
+ g_braceCount = 0;
BEGIN(FunctionParamDefVal);
}
-
- ")" { // end of parameter list
- current->args = argListToString(current->argList);
+ ")" {
+ unput(*yytext);
+ BEGIN(FunctionDec);
}
-
":"{B} {
- g_specialBlock = TRUE; // expecting a docstring
- bodyEntry = current;
- current->bodyLine = yyLineNr;
- BEGIN( FunctionBody );
- }
+ g_defVal.resize(0);
+ g_braceCount = 0;
+ BEGIN(FunctionAnnotation);
+ }
{POUNDCOMMENT} { // a comment
}
{PARAMNONEMPTY} { // Default rule inside arguments.
@@ -996,31 +1006,131 @@ STARTDOCSYMS "##"
}
+<FunctionTypeAnnotation>{
+ "{" |
+ "[" |
+ "(" {
+ ++g_braceCount;
+ g_defVal+=*yytext;
+ }
+ "}" |
+ "]" |
+ ")" {
+ --g_braceCount;
+ g_defVal+=*yytext;
+ }
+ ":" {
+ if (g_braceCount == 0)
+ {
+ current->type = g_defVal.data();
+ unput(*yytext);
+ BEGIN(FunctionDec);
+ }
+ else
+ g_defVal+=*yytext;
+ }
+ "'" {
+ g_defVal+=*yytext;
+ g_copyString=&g_defVal;
+ g_stringContext=FunctionTypeAnnotation;
+ BEGIN(SingleQuoteString);
+ }
+ "\"" {
+ g_defVal+=*yytext;
+ g_copyString=&g_defVal;
+ g_stringContext=FunctionTypeAnnotation;
+ BEGIN(DoubleQuoteString);
+ }
+ \n {
+ g_defVal+=*yytext;
+ incLineNr();
+ }
+ . {
+ g_defVal+=*yytext;
+ }
+}
+
+<FunctionAnnotation>{
+ "{" |
+ "[" |
+ "(" {
+ ++g_braceCount;
+ g_defVal+=*yytext;
+ }
+ "}" |
+ "]" {
+ --g_braceCount;
+ g_defVal+=*yytext;
+ }
+ ")" |
+ "=" |
+ "," {
+ if (g_braceCount == 0)
+ {
+ if (current->argList->getLast())
+ current->argList->getLast()->type += g_defVal.data();
+ if (*yytext != ',')
+ unput(*yytext);
+ BEGIN(FunctionParams);
+ }
+ else
+ {
+ if (*yytext == ')')
+ --g_braceCount;
+ g_defVal += *yytext;
+ }
+ }
+ "'" {
+ g_defVal+=*yytext;
+ g_copyString=&g_defVal;
+ g_stringContext=FunctionAnnotation;
+ BEGIN(SingleQuoteString);
+ }
+ "\"" {
+ g_defVal+=*yytext;
+ g_copyString=&g_defVal;
+ g_stringContext=FunctionAnnotation;
+ BEGIN(DoubleQuoteString);
+ }
+ \n {
+ g_defVal+=*yytext;
+ incLineNr();
+ }
+ . {
+ g_defVal+=*yytext;
+ }
+}
+
<FunctionParamDefVal>{
+ "{" |
"[" |
"(" { // internal opening brace, assumption is that we have correct code so braces do match
- g_braceCount++;
+ ++g_braceCount;
g_defVal+=*yytext;
}
- "," |
- "]" |
- ")" {
- if (g_braceCount==0) // end of default argument
+ "}" |
+ "]" {
+ --g_braceCount;
+ g_defVal+=*yytext;
+ }
+ ")" |
+ "," {
+ if (g_braceCount == 0)
{
if (current->argList->getLast())
- {
current->argList->getLast()->defval=QCString(g_defVal.data()).stripWhiteSpace();
- }
- if (*yytext != ',')
- current->args = argListToString(current->argList);
+ if (*yytext == ')')
+ unput(*yytext);
BEGIN(FunctionParams);
}
- else // continue
- {
- if (*yytext != ',')g_braceCount--;
- g_defVal+=*yytext;
- }
+ else
+ {
+ if (*yytext == ')')
+ --g_braceCount;
+ g_defVal += *yytext;
+ }
}
+
"'" {
g_defVal+=*yytext;
g_copyString=&g_defVal;
diff --git a/src/reflist.cpp b/src/reflist.cpp
index 1da603e..7ae4c80 100644
--- a/src/reflist.cpp
+++ b/src/reflist.cpp
@@ -131,7 +131,15 @@ void RefList::insertIntoList(const char *key,RefItem *item)
{
if (ri!=item)
{
- ri->extraItems.append(item);
+ // We also have to check if the item is not already in the "extra" list
+ QListIterator<RefItem> li(ri->extraItems);
+ RefItem *extraItem;
+ bool doubleItem = false;
+ for (li.toFirst();(extraItem=li.current());++li)
+ {
+ if (item == extraItem) doubleItem = true;
+ }
+ if (!doubleItem) ri->extraItems.append(item);
}
}
}
@@ -148,8 +156,6 @@ void RefList::generatePage()
for (it.toFirst();(item=it.current());++it)
{
doc += " <dt>";
- doc += "\\anchor ";
- doc += item->listAnchor;
doc += "\n";
if (item->scope)
{
@@ -171,15 +177,21 @@ void RefList::generatePage()
if (!item->args.isEmpty())
{
// escape @'s in argument list, needed for Java annotations (see issue #6208)
- doc += substitute(item->args,"@","@@");
+ // escape \'s in argument list (see issue #6533)
+ doc += substitute(substitute(item->args,"@","@@"),"\\","\\\\");
}
- doc += "</dt><dd> ";
+ doc += "</dt><dd> \\anchor ";
+ doc += item->listAnchor;
+ doc += " ";
doc += item->text;
QListIterator<RefItem> li(item->extraItems);
RefItem *extraItem;
for (li.toFirst();(extraItem=li.current());++li)
{
- doc += "<p>" + extraItem->text;
+ doc += "<p> \\anchor ";
+ doc += extraItem->listAnchor;
+ doc += " ";
+ doc += extraItem->text;
}
doc += "</dd>";
}
diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp
index 7fbfdc8..0be2266 100644
--- a/src/rtfdocvisitor.cpp
+++ b/src/rtfdocvisitor.cpp
@@ -1072,7 +1072,7 @@ void RTFDocVisitor::visitPre(DocHtmlHeader *header)
m_t << "{" // start section
<< rtf_Style_Reset;
QCString heading;
- int level = QMIN(header->level()+2,4);
+ int level = QMIN(header->level(),5);
heading.sprintf("Heading%d",level);
// set style
m_t << rtf_Style[heading]->reference;
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index b4a9e65..34af705 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -2180,11 +2180,12 @@ void RTFGenerator::newParagraph()
m_omitParagraph = FALSE;
}
-void RTFGenerator::startParagraph(const char *)
+void RTFGenerator::startParagraph(const char *txt)
{
DBG_RTF(t << "{\\comment startParagraph}" << endl)
newParagraph();
t << "{" << endl;
+ if (QCString(txt) == "reference") t << "\\ql" << endl;
}
void RTFGenerator::endParagraph()
diff --git a/src/scanner.l b/src/scanner.l
index 4846132..e9fca43 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -597,15 +597,11 @@ static int yyread(char *buf,int max_size)
/* start command character */
CMD ("\\"|"@")
-SECTIONCMD {CMD}("image"|"author"|"internal"|"version"|"date"|"deprecated"|"param"|"exception"|"return"[s]?|"retval"|"bug"|"warning"|"par"|"sa"|"see"|"pre"|"post"|"invariant"|"note"|"remark"[s]?|"todo"|"test"|"xrefitem"|"ingroup"|"callgraph"|"callergraph"|"latexonly"|"htmlonly"|"xmlonly"|"docbookonly"|"manonly"|"{"|"verbatim"|"dotfile"|"dot"|"defgroup"|"addtogroup"|"weakgroup"|"class"|"namespace"|"union"|"struct"|"fn"|"var"|"details"|"typedef"|"def"|"overload")|("<"{PRE}">")
BN [ \t\n\r]
BL [ \t\r]*"\n"
B [ \t]
-BS ^(({B}*"//")?)(({B}*"*"+)?){B}*
ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
-SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
SCOPENAME "$"?(({ID}?{BN}*"::"{BN}*)*)(((~|!){BN}*)?{ID})
-PHPSCOPENAME ({ID}"\\")+{ID}
TSCOPE {ID}("<"[a-z_A-Z0-9 \t\*\&,:]*">")?
CSSCOPENAME (({ID}?{BN}*"."{BN}*)*)((~{BN}*)?{ID})
PRE [pP][rR][eE]
@@ -3079,6 +3075,10 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
*pCopyQuotedGString+=*yytext;
BEGIN( lastStringContext );
}
+<CopyGString,CopyPHPGString>"<?php" { // we had an odd number of quotes.
+ *pCopyQuotedGString += yytext;
+ BEGIN( lastStringContext );
+ }
<CopyGString,CopyPHPGString>"/*"|"*/"|"//" {
*pCopyQuotedGString+=yytext;
}
@@ -3840,6 +3840,28 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
else
{
current->endBodyLine = yyLineNr;
+ if (current->section == Entry::NAMESPACE_SEC && current->type == "namespace")
+ {
+ int split_point;
+ while ((split_point = current->name.find("::")) != -1)
+ {
+ Entry *new_current = new Entry(*current);
+ current->program = "";
+ new_current->doc = "";
+ new_current->docLine = 0;
+ new_current->docFile = "";
+ new_current->brief = "";
+ new_current->briefLine = 0;
+ new_current->briefFile = "";
+ new_current->name = current->name.mid(split_point + 2);
+ current->name = current->name.left(split_point);
+ if (!current_root->name.isEmpty()) current->name.prepend(current_root->name+"::");
+
+ current_root->addSubEntry(current);
+ current_root = current;
+ current = new_current;
+ }
+ }
QCString &cn = current->name;
QCString rn = current_root->name.copy();
//printf("cn=`%s' rn=`%s' isTypedef=%d\n",cn.data(),rn.data(),isTypedef);
diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp
index 6cd9581..a7d7f21 100644
--- a/src/sqlite3gen.cpp
+++ b/src/sqlite3gen.cpp
@@ -23,11 +23,15 @@
#include "qtbc.h"
#include "sqlite3gen.h"
#include "doxygen.h"
+#include "xmlgen.h"
+#include "xmldocvisitor.h"
#include "config.h"
#include "util.h"
+#include "outputlist.h"
#include "docparser.h"
#include "language.h"
+#include "version.h"
#include "dot.h"
#include "arguments.h"
#include "classlist.h"
@@ -35,65 +39,129 @@
#include "namespacedef.h"
#include "filename.h"
#include "groupdef.h"
+#include "membername.h"
+#include "memberdef.h"
#include "pagedef.h"
#include "dirdef.h"
+#include "section.h"
+#include <sys/stat.h>
#include <qdir.h>
#include <string.h>
#include <sqlite3.h>
-//#define DBG_CTX(x) printf x
-#define DBG_CTX(x) do { } while(0)
+// enable to show general debug messages
+// #define SQLITE3_DEBUG
-const char * schema_queries[][2] = {
+// enable to print all executed SQL statements.
+// I recommend using the smallest possible input list.
+// #define SQLITE3_DEBUG_SQL
+
+# ifdef SQLITE3_DEBUG
+# define DBG_CTX(x) printf x
+# else // SQLITE3_DEBUG
+# define DBG_CTX(x) do { } while(0)
+# endif
+
+# ifdef SQLITE3_DEBUG_SQL
+// used by sqlite3_trace in generateSqlite3()
+static void sqlLog(void *dbName, const char *sql){
+ msg("SQL: '%s'\n", sql);
+}
+# endif
+
+const char * table_schema[][2] = {
+ /* TABLES */
+ { "meta",
+ "CREATE TABLE IF NOT EXISTS meta (\n"
+ "\t-- Information about this db and how it was generated.\n"
+ "\t-- Doxygen info\n"
+ "\tdoxygen_version TEXT PRIMARY KEY NOT NULL,\n"
+ /*
+ Doxygen's version is likely to rollover much faster than the schema, and
+ at least until it becomes a core output format, we might want to make
+ fairly large schema changes even on minor iterations for Doxygen itself.
+ If these tools just track a predefined semver schema version that can
+ iterate independently, it *might* not be as hard to keep them in sync?
+ */
+ "\tschema_version TEXT NOT NULL, -- Schema-specific semver\n"
+ "\t-- run info\n"
+ "\tgenerated_at TEXT NOT NULL,\n"
+ "\tgenerated_on TEXT NOT NULL,\n"
+ "\t-- project info\n"
+ "\tproject_name TEXT NOT NULL,\n"
+ "\tproject_number TEXT,\n"
+ "\tproject_brief TEXT\n"
+ ");"
+ },
{ "includes",
"CREATE TABLE IF NOT EXISTS includes (\n"
"\t-- #include relations.\n"
"\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
"\tlocal INTEGER NOT NULL,\n"
- "\tid_src INTEGER NOT NULL, -- File id of the includer.\n"
- "\tid_dst INTEGER NOT NULL -- File id of the includee.\n"
- ");\n"
- "CREATE UNIQUE INDEX idx_includes ON includes\n"
- "\t(local, id_src, id_dst);"
+ "\tsrc_id INTEGER NOT NULL REFERENCES path, -- File id of the includer.\n"
+ "\tdst_id INTEGER NOT NULL REFERENCES path, -- File id of the includee.\n"
+ /*
+ In theory we could include name here to be informationally equivalent
+ with the XML, but I don't see an obvious use for it.
+ */
+ "\tUNIQUE(local, src_id, dst_id) ON CONFLICT IGNORE\n"
+ ");"
},
- { "innerclass",
- "CREATE TABLE IF NOT EXISTS innerclass (\n"
+ { "contains",
+ "CREATE TABLE IF NOT EXISTS contains (\n"
+ "\t-- inner/outer relations (file, namespace, dir, class, group, page)\n"
"\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
- "\trefid INTEGER NOT NULL,\n"
- "\tprot INTEGER NOT NULL,\n"
- "\tname TEXT NOT NULL\n"
- ");"
+ "\tinner_rowid INTEGER NOT NULL REFERENCES compounddef,\n"
+ "\touter_rowid INTEGER NOT NULL REFERENCES compounddef\n"
+ ");"
},
- { "files",
- "CREATE TABLE IF NOT EXISTS files (\n"
- "\t-- Names of source files and includes.\n"
- "\tname TEXT PRIMARY KEY NOT NULL\n"
- ");"
+ /* TODO: Path can also share rowids with refid/compounddef/def. (It could
+ * even collapse into that table...)
+ *
+ * I took a first swing at this by changing insertPath() to:
+ * - accept a FileDef
+ * - make its own call to insertRefid
+ * - return a refid struct.
+ *
+ * I rolled this back when I had trouble getting a FileDef for all types
+ * (PageDef in particular).
+ *
+ * Note: all colums referencing path would need an update.
+ */
+ { "path",
+ "CREATE TABLE IF NOT EXISTS path (\n"
+ "\t-- Paths of source files and includes.\n"
+ "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
+ "\ttype INTEGER NOT NULL, -- 1:file 2:dir\n"
+ "\tlocal INTEGER NOT NULL,\n"
+ "\tfound INTEGER NOT NULL,\n"
+ "\tname TEXT NOT NULL\n"
+ ");"
},
- { "refids",
- "CREATE TABLE IF NOT EXISTS refids (\n"
- "\trefid TEXT PRIMARY KEY NOT NULL\n"
- ");"
+ { "refid",
+ "CREATE TABLE IF NOT EXISTS refid (\n"
+ "\t-- Distinct refid for all documented entities.\n"
+ "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
+ "\trefid TEXT NOT NULL UNIQUE\n"
+ ");"
},
{ "xrefs",
"CREATE TABLE IF NOT EXISTS xrefs (\n"
- "\t-- Cross reference relation.\n"
+ "\t-- Cross-reference relation\n"
+ "\t-- (combines xml <referencedby> and <references> nodes).\n"
"\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
- "\trefid_src INTEGER NOT NULL, -- referrer id.\n"
- "\trefid_dst INTEGER NOT NULL, -- referee id.\n"
- "\tid_file INTEGER NOT NULL, -- file where the reference is happening.\n"
- "\tline INTEGER NOT NULL, -- line where the reference is happening.\n"
- "\tcolumn INTEGER NOT NULL -- column where the reference is happening.\n"
- ");\n"
- "CREATE UNIQUE INDEX idx_xrefs ON xrefs\n"
- "\t(refid_src, refid_dst, id_file, line, column);"
+ "\tsrc_rowid INTEGER NOT NULL REFERENCES refid, -- referrer id.\n"
+ "\tdst_rowid INTEGER NOT NULL REFERENCES refid, -- referee id.\n"
+ "\tcontext TEXT NOT NULL, -- inline, argument, initializer\n"
+ "\t-- Just need to know they link; ignore duplicates.\n"
+ "\tUNIQUE(src_rowid, dst_rowid, context) ON CONFLICT IGNORE\n"
+ ");\n"
},
{ "memberdef",
"CREATE TABLE IF NOT EXISTS memberdef (\n"
"\t-- All processed identifiers.\n"
- "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
- "\trefid INTEGER NOT NULL, -- see the refids table\n"
+ "\trowid INTEGER PRIMARY KEY NOT NULL,\n"
"\tname TEXT NOT NULL,\n"
"\tdefinition TEXT,\n"
"\ttype TEXT,\n"
@@ -107,7 +175,7 @@ const char * schema_queries[][2] = {
"\tstatic INTEGER DEFAULT 0, -- 0:no 1:yes\n"
"\tconst INTEGER DEFAULT 0, -- 0:no 1:yes\n"
"\texplicit INTEGER DEFAULT 0, -- 0:no 1:yes\n"
- "\tinline INTEGER DEFAULT 0, -- 0:no 1:yes\n"
+ "\tinline INTEGER DEFAULT 0, -- 0:no 1:yes 2:both (set after encountering inline and not-inline)\n"
"\tfinal INTEGER DEFAULT 0, -- 0:no 1:yes\n"
"\tsealed INTEGER DEFAULT 0, -- 0:no 1:yes\n"
"\tnew INTEGER DEFAULT 0, -- 0:no 1:yes\n"
@@ -138,55 +206,71 @@ const char * schema_queries[][2] = {
"\taddable INTEGER DEFAULT 0, -- 0:no 1:yes\n"
"\tremovable INTEGER DEFAULT 0, -- 0:no 1:yes\n"
"\traisable INTEGER DEFAULT 0, -- 0:no 1:yes\n"
- /// @todo make a `kind' table
- "\tkind INTEGER DEFAULT 0, -- 0:define 1:function 2:variable 3:typedef 4:enum 5:enumvalue 6:signal 7:slot 8:friend 9:DCOP 10:property 11:event\n"
+ "\tkind TEXT NOT NULL, -- 'macro definition' 'function' 'variable' 'typedef' 'enumeration' 'enumvalue' 'signal' 'slot' 'friend' 'dcop' 'property' 'event' 'interface' 'service'\n"
"\tbodystart INTEGER DEFAULT 0, -- starting line of definition\n"
"\tbodyend INTEGER DEFAULT 0, -- ending line of definition\n"
- "\tid_bodyfile INTEGER DEFAULT 0, -- file of definition\n"
- "\tid_file INTEGER NOT NULL, -- file where this identifier is located\n"
+ "\tbodyfile_id INTEGER REFERENCES path, -- file of definition\n"
+ "\tfile_id INTEGER NOT NULL REFERENCES path, -- file where this identifier is located\n"
"\tline INTEGER NOT NULL, -- line where this identifier is located\n"
"\tcolumn INTEGER NOT NULL, -- column where this identifier is located\n"
- /// @todo make a `detaileddescription' table
"\tdetaileddescription TEXT,\n"
"\tbriefdescription TEXT,\n"
- "\tinbodydescription TEXT\n"
- ");"
+ "\tinbodydescription TEXT,\n"
+ "\tFOREIGN KEY (rowid) REFERENCES refid (rowid)\n"
+ ");"
+ },
+ { "member",
+ "CREATE TABLE IF NOT EXISTS member (\n"
+ "\t-- Memberdef <-> containing compound relation.\n"
+ "\t-- Similar to XML listofallmembers.\n"
+ "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
+ "\tscope_rowid INTEGER NOT NULL REFERENCES compounddef,\n"
+ "\tmemberdef_rowid INTEGER NOT NULL REFERENCES memberdef,\n"
+ "\tprot INTEGER NOT NULL,\n"
+ "\tvirt INTEGER NOT NULL,\n"
+ "\tUNIQUE(scope_rowid, memberdef_rowid)\n"
+ ");"
+ },
+ { "reimplements",
+ "CREATE TABLE IF NOT EXISTS reimplements (\n"
+ "\t-- Inherited member reimplmentation relations.\n"
+ "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
+ "\tmemberdef_rowid INTEGER NOT NULL REFERENCES memberdef, -- reimplementing memberdef id.\n"
+ "\treimplemented_rowid INTEGER NOT NULL REFERENCES memberdef, -- reimplemented memberdef id.\n"
+ "\tUNIQUE(memberdef_rowid, reimplemented_rowid) ON CONFLICT IGNORE\n"
+ ");\n"
},
{ "compounddef",
"CREATE TABLE IF NOT EXISTS compounddef (\n"
- "\t-- class/struct definitions.\n"
- "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
- "\tname TEXT NOT NULL,\n"
- "\tkind TEXT NOT NULL,\n"
- "\trefid INTEGER NOT NULL,\n"
- "\tprot INTEGER NOT NULL,\n"
- "\tid_file INTEGER NOT NULL,\n"
- "\tline INTEGER NOT NULL,\n"
- "\tcolumn INTEGER NOT NULL\n"
- ");"
- },
- { "basecompoundref",
- "CREATE TABLE IF NOT EXISTS basecompoundref (\n"
- "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
- "\tbase TEXT NOT NULL,\n"
- "\tderived TEXT NOT NULL,\n"
- "\trefid INTEGER NOT NULL,\n"
- "\tprot INTEGER NOT NULL,\n"
- "\tvirt INTEGER NOT NULL\n"
- ");"
+ "\t-- Class/struct definitions.\n"
+ "\trowid INTEGER PRIMARY KEY NOT NULL,\n"
+ "\tname TEXT NOT NULL,\n"
+ "\ttitle TEXT,\n"
+ // probably won't be empty '' or unknown, but the source *could* return them...
+ "\tkind TEXT NOT NULL, -- 'category' 'class' 'constants' 'dir' 'enum' 'example' 'exception' 'file' 'group' 'interface' 'library' 'module' 'namespace' 'package' 'page' 'protocol' 'service' 'singleton' 'struct' 'type' 'union' 'unknown' ''\n"
+ "\tprot INTEGER,\n"
+ "\tfile_id INTEGER NOT NULL REFERENCES path,\n"
+ "\tline INTEGER NOT NULL,\n"
+ "\tcolumn INTEGER NOT NULL,\n"
+ "\theader_id INTEGER REFERENCES path,\n"
+ "\tdetaileddescription TEXT,\n"
+ "\tbriefdescription TEXT,\n"
+ "\tFOREIGN KEY (rowid) REFERENCES refid (rowid)\n"
+ ");"
},
- { "derivedcompoundref",
- "CREATE TABLE IF NOT EXISTS derivedcompoundref (\n"
- "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
- "\tbase TEXT NOT NULL,\n"
- "\tderived TEXT NOT NULL,\n"
- "\trefid INTEGER NOT NULL,\n"
- "\tprot INTEGER NOT NULL,\n"
- "\tvirt INTEGER NOT NULL\n"
- ");"
+ { "compoundref",
+ "CREATE TABLE IF NOT EXISTS compoundref (\n"
+ "\t-- Inheritance relation.\n"
+ "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
+ "\tbase_rowid INTEGER NOT NULL REFERENCES compounddef,\n"
+ "\tderived_rowid INTEGER NOT NULL REFERENCES compounddef,\n"
+ "\tprot INTEGER NOT NULL,\n"
+ "\tvirt INTEGER NOT NULL,\n"
+ "\tUNIQUE(base_rowid, derived_rowid)\n"
+ ");"
},
- { "params",
- "CREATE TABLE IF NOT EXISTS params (\n"
+ { "param",
+ "CREATE TABLE IF NOT EXISTS param (\n"
"\t-- All processed parameters.\n"
"\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
"\tattributes TEXT,\n"
@@ -196,24 +280,222 @@ const char * schema_queries[][2] = {
"\tarray TEXT,\n"
"\tdefval TEXT,\n"
"\tbriefdescription TEXT\n"
- ");"
- "CREATE UNIQUE INDEX idx_params ON params\n"
+ ");"
+ "CREATE UNIQUE INDEX idx_param ON param\n"
"\t(type, defname);"
},
- { "memberdef_params",
- "CREATE TABLE IF NOT EXISTS memberdef_params (\n"
+ { "memberdef_param",
+ "CREATE TABLE IF NOT EXISTS memberdef_param (\n"
"\t-- Junction table for memberdef parameters.\n"
"\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
- "\tid_memberdef INTEGER NOT NULL,\n"
- "\tid_param INTEGER NOT NULL\n"
- ");"
+ "\tmemberdef_id INTEGER NOT NULL REFERENCES memberdef,\n"
+ "\tparam_id INTEGER NOT NULL REFERENCES param\n"
+ ");"
},
- { "innernamespaces",
- "CREATE TABLE IF NOT EXISTS innernamespaces (\n"
- "\trowid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n"
- "\trefid INTEGER NOT NULL,\n"
- "\tname TEXT NOT NULL\n"
- ");"
+};
+ const char * view_schema[][2] = {
+ /* VIEWS *
+ We'll set these up AFTER we build the database, so that they can be indexed,
+ but so we don't have to pay a performance penalty for inserts as we build.
+ */
+ {
+ /*
+ Makes all reference/relation tables easier to use. For example:
+ 1. query xrefs and join this view on either xrefs.dst_rowid=def.rowid or
+ xrefs.src_rowid=def.rowid
+ 2. get everything you need to output a list of references to/from an entity
+
+ Also supports simple name search/lookup for both compound and member types.
+
+ NOTES:
+ - summary for compounds generalizes title and briefdescription because
+ there's no single field that works as a quick introduction for both
+ pages and classes
+ - May be value in eventually extending this to fulltext or levenshtein
+ distance-driven lookup/search, but I'm avoiding these for now as it
+ takes some effort to enable them.
+ */
+ "def",
+ "CREATE VIEW IF NOT EXISTS def (\n"
+ "\t-- Combined summary of all -def types for easier joins.\n"
+ "\trowid,\n"
+ "\trefid,\n"
+ "\tkind,\n"
+ "\tname,\n"
+ "\tsummary"
+ ")\n"
+ "as SELECT \n"
+ "\trefid.rowid,\n"
+ "\trefid.refid,\n"
+ "\tmemberdef.kind,\n"
+ "\tmemberdef.name,\n"
+ "\tmemberdef.briefdescription \n"
+ "FROM refid \n"
+ "JOIN memberdef ON refid.rowid=memberdef.rowid \n"
+ "UNION ALL \n"
+ "SELECT \n"
+ "\trefid.rowid,\n"
+ "\trefid.refid,\n"
+ "\tcompounddef.kind,\n"
+ "\tcompounddef.name,\n"
+ "\tCASE \n"
+ "\t\tWHEN briefdescription IS NOT NULL \n"
+ "\t\tTHEN briefdescription \n"
+ "\t\tELSE title \n"
+ "\tEND summary\n"
+ "FROM refid \n"
+ "JOIN compounddef ON refid.rowid=compounddef.rowid;"
+ },
+ {
+ "local_file",
+ "CREATE VIEW IF NOT EXISTS local_file (\n"
+ "\t-- File paths found within the project.\n"
+ "\trowid,\n"
+ "\tfound,\n"
+ "\tname\n"
+ ")\n"
+ "as SELECT \n"
+ "\tpath.rowid,\n"
+ "\tpath.found,\n"
+ "\tpath.name\n"
+ "FROM path WHERE path.type=1 AND path.local=1 AND path.found=1;\n"
+ },
+ {
+ "external_file",
+ "CREATE VIEW IF NOT EXISTS external_file (\n"
+ "\t-- File paths outside the project (found or not).\n"
+ "\trowid,\n"
+ "\tfound,\n"
+ "\tname\n"
+ ")\n"
+ "as SELECT \n"
+ "\tpath.rowid,\n"
+ "\tpath.found,\n"
+ "\tpath.name\n"
+ "FROM path WHERE path.type=1 AND path.local=0;\n"
+ },
+ {
+ "inline_xrefs",
+ "CREATE VIEW IF NOT EXISTS inline_xrefs (\n"
+ "\t-- Crossrefs from inline member source.\n"
+ "\trowid,\n"
+ "\tsrc_rowid,\n"
+ "\tdst_rowid\n"
+ ")\n"
+ "as SELECT \n"
+ "\txrefs.rowid,\n"
+ "\txrefs.src_rowid,\n"
+ "\txrefs.dst_rowid\n"
+ "FROM xrefs WHERE xrefs.context='inline';\n"
+ },
+ {
+ "argument_xrefs",
+ "CREATE VIEW IF NOT EXISTS argument_xrefs (\n"
+ "\t-- Crossrefs from member def/decl arguments\n"
+ "\trowid,\n"
+ "\tsrc_rowid,\n"
+ "\tdst_rowid\n"
+ ")\n"
+ "as SELECT \n"
+ "\txrefs.rowid,\n"
+ "\txrefs.src_rowid,\n"
+ "\txrefs.dst_rowid\n"
+ "FROM xrefs WHERE xrefs.context='argument';\n"
+ },
+ {
+ "initializer_xrefs",
+ "CREATE VIEW IF NOT EXISTS initializer_xrefs (\n"
+ "\t-- Crossrefs from member initializers\n"
+ "\trowid,\n"
+ "\tsrc_rowid,\n"
+ "\tdst_rowid\n"
+ ")\n"
+ "as SELECT \n"
+ "\txrefs.rowid,\n"
+ "\txrefs.src_rowid,\n"
+ "\txrefs.dst_rowid\n"
+ "FROM xrefs WHERE xrefs.context='initializer';\n"
+ },
+ {
+ "inner_outer",
+ "CREATE VIEW IF NOT EXISTS inner_outer\n"
+ "\t-- Joins 'contains' relations to simplify inner/outer 'rel' queries.\n"
+ "as SELECT \n"
+ "\tinner.*,\n"
+ "\touter.*\n"
+ "FROM def as inner\n"
+ "\tJOIN contains ON inner.rowid=contains.inner_rowid\n"
+ "\tJOIN def AS outer ON outer.rowid=contains.outer_rowid;\n"
+ },
+ {
+ "rel",
+ "CREATE VIEW IF NOT EXISTS rel (\n"
+ "\t-- Boolean indicator of relations available for a given entity.\n"
+ "\t-- Join to (compound-|member-)def to find fetch-worthy relations.\n"
+ "\trowid,\n"
+ "\treimplemented,\n"
+ "\treimplements,\n"
+ "\tinnercompounds,\n"
+ "\toutercompounds,\n"
+ "\tinnerpages,\n"
+ "\touterpages,\n"
+ "\tinnerdirs,\n"
+ "\touterdirs,\n"
+ "\tinnerfiles,\n"
+ "\touterfiles,\n"
+ "\tinnerclasses,\n"
+ "\touterclasses,\n"
+ "\tinnernamespaces,\n"
+ "\touternamespaces,\n"
+ "\tinnergroups,\n"
+ "\toutergroups,\n"
+ "\tmembers,\n"
+ "\tcompounds,\n"
+ "\tsubclasses,\n"
+ "\tsuperclasses,\n"
+ "\tlinks_in,\n"
+ "\tlinks_out,\n"
+ "\targument_links_in,\n"
+ "\targument_links_out,\n"
+ "\tinitializer_links_in,\n"
+ "\tinitializer_links_out\n"
+ ")\n"
+ "as SELECT \n"
+ "\tdef.rowid,\n"
+ "\tEXISTS (SELECT rowid FROM reimplements WHERE reimplemented_rowid=def.rowid),\n"
+ "\tEXISTS (SELECT rowid FROM reimplements WHERE memberdef_rowid=def.rowid),\n"
+ "\t-- rowid/kind for inner, [rowid:1/kind:1] for outer\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind='page'),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1]='page'),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind='dir'),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1]='dir'),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind='file'),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1]='file'),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind in (\n"
+ "'category','class','enum','exception','interface','module','protocol',\n"
+ "'service','singleton','struct','type','union'\n"
+ ")),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1] in (\n"
+ "'category','class','enum','exception','interface','module','protocol',\n"
+ "'service','singleton','struct','type','union'\n"
+ ")),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind='namespace'),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1]='namespace'),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE [rowid:1]=def.rowid AND kind='group'),\n"
+ "\tEXISTS (SELECT * FROM inner_outer WHERE rowid=def.rowid AND [kind:1]='group'),\n"
+ "\tEXISTS (SELECT rowid FROM member WHERE scope_rowid=def.rowid),\n"
+ "\tEXISTS (SELECT rowid FROM member WHERE memberdef_rowid=def.rowid),\n"
+ "\tEXISTS (SELECT rowid FROM compoundref WHERE base_rowid=def.rowid),\n"
+ "\tEXISTS (SELECT rowid FROM compoundref WHERE derived_rowid=def.rowid),\n"
+ "\tEXISTS (SELECT rowid FROM inline_xrefs WHERE dst_rowid=def.rowid),\n"
+ "\tEXISTS (SELECT rowid FROM inline_xrefs WHERE src_rowid=def.rowid),\n"
+ "\tEXISTS (SELECT rowid FROM argument_xrefs WHERE dst_rowid=def.rowid),\n"
+ "\tEXISTS (SELECT rowid FROM argument_xrefs WHERE src_rowid=def.rowid),\n"
+ "\tEXISTS (SELECT rowid FROM initializer_xrefs WHERE dst_rowid=def.rowid),\n"
+ "\tEXISTS (SELECT rowid FROM initializer_xrefs WHERE src_rowid=def.rowid)\n"
+ "FROM def ORDER BY def.rowid;"
}
};
@@ -224,193 +506,298 @@ struct SqlStmt {
sqlite3 *db;
};
//////////////////////////////////////////////////////
-SqlStmt incl_insert = { "INSERT INTO includes "
- "( local, id_src, id_dst ) "
- "VALUES "
- "(:local,:id_src,:id_dst )"
- ,NULL
+/* If you add a new statement below, make sure to add it to
+ prepareStatements(). If sqlite3 is segfaulting (especially in
+ sqlite3_clear_bindings()), using an un-prepared statement may
+ be the cause. */
+SqlStmt meta_insert = {
+ "INSERT INTO meta "
+ "( doxygen_version, schema_version, generated_at, generated_on, project_name, project_number, project_brief )"
+ "VALUES "
+ "(:doxygen_version,:schema_version,:generated_at,:generated_on,:project_name,:project_number,:project_brief )"
+ ,NULL
+};
+//////////////////////////////////////////////////////
+SqlStmt incl_insert = {
+ "INSERT INTO includes "
+ "( local, src_id, dst_id ) "
+ "VALUES "
+ "(:local,:src_id,:dst_id )"
+ ,NULL
};
-SqlStmt incl_select = { "SELECT COUNT(*) FROM includes WHERE "
- "local=:local AND id_src=:id_src AND id_dst=:id_dst"
- ,NULL
+SqlStmt incl_select = {
+ "SELECT COUNT(*) FROM includes WHERE "
+ "local=:local AND src_id=:src_id AND dst_id=:dst_id"
+ ,NULL
};
//////////////////////////////////////////////////////
-SqlStmt innerclass_insert={"INSERT INTO innerclass "
- "( refid, prot, name )"
- "VALUES "
- "(:refid,:prot,:name )"
- ,NULL
+SqlStmt contains_insert={
+ "INSERT INTO contains "
+ "( inner_rowid, outer_rowid )"
+ "VALUES "
+ "(:inner_rowid,:outer_rowid )"
+ ,NULL
};
//////////////////////////////////////////////////////
-SqlStmt files_select = {"SELECT rowid FROM files WHERE name=:name"
+SqlStmt path_select = {
+ "SELECT rowid FROM path WHERE name=:name"
,NULL
};
-SqlStmt files_insert = {"INSERT INTO files "
- "( name )"
- "VALUES "
- "(:name )"
- ,NULL
+SqlStmt path_insert = {
+ "INSERT INTO path "
+ "( type, local, found, name )"
+ "VALUES "
+ "(:type,:local,:found,:name )"
+ ,NULL
};
//////////////////////////////////////////////////////
-SqlStmt refids_select = {"SELECT rowid FROM refids WHERE "
- "refid=:refid"
- ,NULL
+SqlStmt refid_select = {
+ "SELECT rowid FROM refid WHERE refid=:refid"
+ ,NULL
};
-SqlStmt refids_insert = {"INSERT INTO refids "
- "( refid )"
- "VALUES "
+SqlStmt refid_insert = {
+ "INSERT INTO refid "
+ "( refid )"
+ "VALUES "
"(:refid )"
- ,NULL
+ ,NULL
};
//////////////////////////////////////////////////////
-SqlStmt xrefs_insert= {"INSERT INTO xrefs "
- "( refid_src, refid_dst, id_file, line, column )"
- "VALUES "
- "(:refid_src,:refid_dst,:id_file,:line,:column )"
- ,NULL
+SqlStmt xrefs_insert= {
+ "INSERT INTO xrefs "
+ "( src_rowid, dst_rowid, context )"
+ "VALUES "
+ "(:src_rowid,:dst_rowid,:context )"
+ ,NULL
+};//////////////////////////////////////////////////////
+SqlStmt reimplements_insert= {
+ "INSERT INTO reimplements "
+ "( memberdef_rowid, reimplemented_rowid )"
+ "VALUES "
+ "(:memberdef_rowid,:reimplemented_rowid )"
+ ,NULL
};
//////////////////////////////////////////////////////
-SqlStmt memberdef_insert={"INSERT INTO memberdef "
- "("
- "refid,"
- "name,"
- "definition,"
- "type,"
- "argsstring,"
- "scope,"
- "initializer,"
- "bitfield,"
- "read,"
- "write,"
- "prot,"
- "static,"
- "const,"
- "explicit,"
- "inline,"
- "final,"
- "sealed,"
- "new,"
- "optional,"
- "required,"
- "volatile,"
- "virt,"
- "mutable,"
- "initonly,"
- "attribute,"
- "property,"
- "readonly,"
- "bound,"
- "constrained,"
- "transient,"
- "maybevoid,"
- "maybedefault,"
- "maybeambiguous,"
- "readable,"
- "writable,"
- "gettable,"
- "protectedsettable,"
- "protectedgettable,"
- "settable,"
- "privatesettable,"
- "privategettable,"
- "accessor,"
- "addable,"
- "removable,"
- "raisable,"
- "kind,"
- "bodystart,"
- "bodyend,"
- "id_bodyfile,"
- "id_file,"
- "line,"
- "column,"
- "detaileddescription,"
- "briefdescription,"
- "inbodydescription"
- ")"
- "VALUES "
- "("
- ":refid,"
- ":name,"
- ":definition,"
- ":type,"
- ":argsstring,"
- ":scope,"
- ":initializer,"
- ":bitfield,"
- ":read,"
- ":write,"
- ":prot,"
- ":static,"
- ":const,"
- ":explicit,"
- ":inline,"
- ":final,"
- ":sealed,"
- ":new,"
- ":optional,"
- ":required,"
- ":volatile,"
- ":virt,"
- ":mutable,"
- ":initonly,"
- ":attribute,"
- ":property,"
- ":readonly,"
- ":bound,"
- ":constrained,"
- ":transient,"
- ":maybevoid,"
- ":maybedefault,"
- ":maybeambiguous,"
- ":readable,"
- ":writable,"
- ":gettable,"
- ":protectedsettable,"
- ":protectedgettable,"
- ":settable,"
- ":privatesettable,"
- ":privategettable,"
- ":accessor,"
- ":addable,"
- ":removable,"
- ":raisable,"
- ":kind,"
- ":bodystart,"
- ":bodyend,"
- ":id_bodyfile,"
- ":id_file,"
- ":line,"
- ":column,"
- ":detaileddescription,"
- ":briefdescription,"
- ":inbodydescription"
- ")"
- ,NULL
+SqlStmt memberdef_exists={
+ "SELECT EXISTS (SELECT * FROM memberdef WHERE rowid = :rowid)"
+ ,NULL
+};
+
+SqlStmt memberdef_incomplete={
+ "SELECT EXISTS ("
+ "SELECT * FROM memberdef WHERE "
+ "rowid = :rowid AND inline != 2 AND inline != :new_inline"
+ ")"
+ ,NULL
+};
+
+SqlStmt memberdef_insert={
+ "INSERT INTO memberdef "
+ "("
+ "rowid,"
+ "name,"
+ "definition,"
+ "type,"
+ "argsstring,"
+ "scope,"
+ "initializer,"
+ "bitfield,"
+ "read,"
+ "write,"
+ "prot,"
+ "static,"
+ "const,"
+ "explicit,"
+ "inline,"
+ "final,"
+ "sealed,"
+ "new,"
+ "optional,"
+ "required,"
+ "volatile,"
+ "virt,"
+ "mutable,"
+ "initonly,"
+ "attribute,"
+ "property,"
+ "readonly,"
+ "bound,"
+ "constrained,"
+ "transient,"
+ "maybevoid,"
+ "maybedefault,"
+ "maybeambiguous,"
+ "readable,"
+ "writable,"
+ "gettable,"
+ "protectedsettable,"
+ "protectedgettable,"
+ "settable,"
+ "privatesettable,"
+ "privategettable,"
+ "accessor,"
+ "addable,"
+ "removable,"
+ "raisable,"
+ "kind,"
+ "bodystart,"
+ "bodyend,"
+ "bodyfile_id,"
+ "file_id,"
+ "line,"
+ "column,"
+ "detaileddescription,"
+ "briefdescription,"
+ "inbodydescription"
+ ")"
+ "VALUES "
+ "("
+ ":rowid,"
+ ":name,"
+ ":definition,"
+ ":type,"
+ ":argsstring,"
+ ":scope,"
+ ":initializer,"
+ ":bitfield,"
+ ":read,"
+ ":write,"
+ ":prot,"
+ ":static,"
+ ":const,"
+ ":explicit,"
+ ":inline,"
+ ":final,"
+ ":sealed,"
+ ":new,"
+ ":optional,"
+ ":required,"
+ ":volatile,"
+ ":virt,"
+ ":mutable,"
+ ":initonly,"
+ ":attribute,"
+ ":property,"
+ ":readonly,"
+ ":bound,"
+ ":constrained,"
+ ":transient,"
+ ":maybevoid,"
+ ":maybedefault,"
+ ":maybeambiguous,"
+ ":readable,"
+ ":writable,"
+ ":gettable,"
+ ":protectedsettable,"
+ ":protectedgettable,"
+ ":settable,"
+ ":privatesettable,"
+ ":privategettable,"
+ ":accessor,"
+ ":addable,"
+ ":removable,"
+ ":raisable,"
+ ":kind,"
+ ":bodystart,"
+ ":bodyend,"
+ ":bodyfile_id,"
+ ":file_id,"
+ ":line,"
+ ":column,"
+ ":detaileddescription,"
+ ":briefdescription,"
+ ":inbodydescription"
+ ")"
+ ,NULL
+};
+/*
+We have a slightly different need than the XML here. The XML can have two
+memberdef nodes with the same refid to document the declaration and the
+definition. This doesn't play very nice with a referential model. It isn't a
+big issue if only one is documented, but in case both are, we'll fall back on
+this kludge to combine them in a single row...
+*/
+SqlStmt memberdef_update_decl={
+ "UPDATE memberdef SET "
+ "inline = :inline,"
+ "file_id = :file_id,"
+ "line = :line,"
+ "column = :column,"
+ "detaileddescription = 'Declaration: ' || :detaileddescription || 'Definition: ' || detaileddescription,"
+ "briefdescription = 'Declaration: ' || :briefdescription || 'Definition: ' || briefdescription,"
+ "inbodydescription = 'Declaration: ' || :inbodydescription || 'Definition: ' || inbodydescription "
+ "WHERE rowid = :rowid"
+ ,NULL
+};
+SqlStmt memberdef_update_def={
+ "UPDATE memberdef SET "
+ "inline = :inline,"
+ "bodystart = :bodystart,"
+ "bodyend = :bodyend,"
+ "bodyfile_id = :bodyfile_id,"
+ "detaileddescription = 'Declaration: ' || detaileddescription || 'Definition: ' || :detaileddescription,"
+ "briefdescription = 'Declaration: ' || briefdescription || 'Definition: ' || :briefdescription,"
+ "inbodydescription = 'Declaration: ' || inbodydescription || 'Definition: ' || :inbodydescription "
+ "WHERE rowid = :rowid"
+ ,NULL
};
//////////////////////////////////////////////////////
-SqlStmt compounddef_insert={"INSERT INTO compounddef "
- "( name, kind, prot, refid, id_file, line, column ) "
- "VALUES "
- "(:name,:kind,:prot,:refid,:id_file,:line,:column )"
- ,NULL
+SqlStmt member_insert={
+ "INSERT INTO member "
+ "( scope_rowid, memberdef_rowid, prot, virt ) "
+ "VALUES "
+ "(:scope_rowid,:memberdef_rowid,:prot,:virt )"
+ ,NULL
};
//////////////////////////////////////////////////////
-SqlStmt basecompoundref_insert={"INSERT INTO basecompoundref "
- "( base, derived, refid, prot, virt ) "
- "VALUES "
- "(:base,:derived,:refid,:prot,:virt )"
- ,NULL
+SqlStmt compounddef_insert={
+ "INSERT INTO compounddef "
+ "("
+ "rowid,"
+ "name,"
+ "title,"
+ "kind,"
+ "prot,"
+ "file_id,"
+ "line,"
+ "column,"
+ "header_id,"
+ "briefdescription,"
+ "detaileddescription"
+ ")"
+ "VALUES "
+ "("
+ ":rowid,"
+ ":name,"
+ ":title,"
+ ":kind,"
+ ":prot,"
+ ":file_id,"
+ ":line,"
+ ":column,"
+ ":header_id,"
+ ":briefdescription,"
+ ":detaileddescription"
+ ")"
+ ,NULL
+};
+SqlStmt compounddef_exists={
+ "SELECT EXISTS ("
+ "SELECT * FROM compounddef WHERE rowid = :rowid"
+ ")"
+ ,NULL
};
//////////////////////////////////////////////////////
-SqlStmt derivedcompoundref_insert={"INSERT INTO derivedcompoundref "
- "( refid, prot, virt, base, derived ) "
- "VALUES "
- "(:refid,:prot,:virt,:base,:derived )"
- ,NULL
+SqlStmt compoundref_insert={
+ "INSERT INTO compoundref "
+ "( base_rowid, derived_rowid, prot, virt ) "
+ "VALUES "
+ "(:base_rowid,:derived_rowid,:prot,:virt )"
+ ,NULL
};
//////////////////////////////////////////////////////
-SqlStmt params_select = { "SELECT rowid FROM params WHERE "
+SqlStmt param_select = {
+ "SELECT rowid FROM param WHERE "
"(attributes IS NULL OR attributes=:attributes) AND "
"(type IS NULL OR type=:type) AND "
"(declname IS NULL OR declname=:declname) AND "
@@ -418,27 +805,22 @@ SqlStmt params_select = { "SELECT rowid FROM params WHERE "
"(array IS NULL OR array=:array) AND "
"(defval IS NULL OR defval=:defval) AND "
"(briefdescription IS NULL OR briefdescription=:briefdescription)"
- ,NULL
+ ,NULL
};
-SqlStmt params_insert = { "INSERT INTO params "
- "( attributes, type, declname, defname, array, defval, briefdescription ) "
- "VALUES "
+SqlStmt param_insert = {
+ "INSERT INTO param "
+ "( attributes, type, declname, defname, array, defval, briefdescription ) "
+ "VALUES "
"(:attributes,:type,:declname,:defname,:array,:defval,:briefdescription)"
- ,NULL
-};
-//////////////////////////////////////////////////////
-SqlStmt memberdef_params_insert={ "INSERT INTO memberdef_params "
- "( id_memberdef, id_param)"
- "VALUES "
- "(:id_memberdef,:id_param)"
- ,NULL
+ ,NULL
};
//////////////////////////////////////////////////////
-SqlStmt innernamespace_insert={"INSERT INTO innernamespaces "
- "( refid, name)"
- "VALUES "
- "(:refid,:name)",
- NULL
+SqlStmt memberdef_param_insert={
+ "INSERT INTO memberdef_param "
+ "( memberdef_id, param_id)"
+ "VALUES "
+ "(:memberdef_id,:param_id)"
+ ,NULL
};
@@ -491,7 +873,7 @@ static bool bindIntParameter(SqlStmt &s,const char *name,int value)
{
int idx = sqlite3_bind_parameter_index(s.stmt, name);
if (idx==0) {
- msg("sqlite3_bind_parameter_index(%s)[%s] failed: %s\n", name, s.query, sqlite3_errmsg(s.db));
+ msg("sqlite3_bind_parameter_index(%s)[%s] failed to find column: %s\n", name, s.query, sqlite3_errmsg(s.db));
return false;
}
int rv = sqlite3_bind_int(s.stmt, idx, value);
@@ -508,7 +890,7 @@ static int step(SqlStmt &s,bool getRowId=FALSE, bool select=FALSE)
int rc = sqlite3_step(s.stmt);
if (rc!=SQLITE_DONE && rc!=SQLITE_ROW)
{
- msg("sqlite3_step: %s\n", sqlite3_errmsg(s.db));
+ DBG_CTX(("sqlite3_step: %s (rc: %d)\n", sqlite3_errmsg(s.db), rc));
sqlite3_reset(s.stmt);
sqlite3_clear_bindings(s.stmt);
return -1;
@@ -520,72 +902,118 @@ static int step(SqlStmt &s,bool getRowId=FALSE, bool select=FALSE)
return rowid;
}
-static int insertFile(const char* name)
+static int insertPath(QCString name, bool local=TRUE, bool found=TRUE, int type=1)
{
int rowid=-1;
if (name==0) return rowid;
- bindTextParameter(files_select,":name",name);
- rowid=step(files_select,TRUE,TRUE);
+ name = stripFromPath(name);
+
+ bindTextParameter(path_select,":name",name.data(),FALSE);
+ rowid=step(path_select,TRUE,TRUE);
if (rowid==0)
{
- bindTextParameter(files_insert,":name",name);
- rowid=step(files_insert,TRUE);
+ bindTextParameter(path_insert,":name",name.data(),FALSE);
+ bindIntParameter(path_insert,":type",type);
+ bindIntParameter(path_insert,":local",local?1:0);
+ bindIntParameter(path_insert,":found",found?1:0);
+ rowid=step(path_insert,TRUE);
}
return rowid;
}
-static int insertRefid(const char *refid)
+static void recordMetadata()
{
- int rowid=-1;
- if (refid==0) return rowid;
+ bindTextParameter(meta_insert,":doxygen_version",versionString);
+ bindTextParameter(meta_insert,":schema_version","0.2.0"); //TODO: this should be a constant somewhere; not sure where
+ bindTextParameter(meta_insert,":generated_at",dateToString(TRUE), FALSE);
+ bindTextParameter(meta_insert,":generated_on",dateToString(FALSE), FALSE);
+ bindTextParameter(meta_insert,":project_name",Config_getString(PROJECT_NAME));
+ bindTextParameter(meta_insert,":project_number",Config_getString(PROJECT_NUMBER));
+ bindTextParameter(meta_insert,":project_brief",Config_getString(PROJECT_BRIEF));
+ step(meta_insert);
+}
- bindTextParameter(refids_select,":refid",refid);
- rowid=step(refids_select,TRUE,TRUE);
- if (rowid==0)
+struct Refid {
+ int rowid;
+ const char *refid;
+ bool created;
+};
+
+struct Refid insertRefid(const char *refid)
+{
+ struct Refid ret;
+ ret.rowid=-1;
+ ret.refid=refid;
+ ret.created = FALSE;
+ if (refid==0) return ret;
+
+ bindTextParameter(refid_select,":refid",refid);
+ ret.rowid=step(refid_select,TRUE,TRUE);
+ if (ret.rowid==0)
{
- bindTextParameter(refids_insert,":refid",refid);
- rowid=step(refids_insert,TRUE);
+ bindTextParameter(refid_insert,":refid",refid);
+ ret.rowid=step(refid_insert,TRUE);
+ ret.created = TRUE;
}
- return rowid;
+
+ return ret;
+}
+
+static bool memberdefExists(struct Refid refid)
+{
+ bindIntParameter(memberdef_exists,":rowid",refid.rowid);
+ int test = step(memberdef_exists,TRUE,TRUE);
+ return test ? true : false;
}
+static bool memberdefIncomplete(struct Refid refid, const MemberDef* md)
+{
+ bindIntParameter(memberdef_incomplete,":rowid",refid.rowid);
+ bindIntParameter(memberdef_incomplete,":new_inline",md->isInline());
+ int test = step(memberdef_incomplete,TRUE,TRUE);
+ return test ? true : false;
+}
-static bool insertMemberReference(int refid_src, int refid_dst,
- int id_file, int line, int column)
+static bool compounddefExists(struct Refid refid)
{
- if (id_file==-1||refid_src==-1||refid_dst==-1)
+ bindIntParameter(compounddef_exists,":rowid",refid.rowid);
+ int test = step(compounddef_exists,TRUE,TRUE);
+ return test ? true : false;
+}
+
+static bool insertMemberReference(struct Refid src_refid, struct Refid dst_refid, const char *context)
+{
+ if (src_refid.rowid==-1||dst_refid.rowid==-1)
return false;
if (
- !bindIntParameter(xrefs_insert,":refid_src",refid_src) ||
- !bindIntParameter(xrefs_insert,":refid_dst",refid_dst) ||
- !bindIntParameter(xrefs_insert,":id_file",id_file) ||
- !bindIntParameter(xrefs_insert,":line",line) ||
- !bindIntParameter(xrefs_insert,":column",column)
+ !bindIntParameter(xrefs_insert,":src_rowid",src_refid.rowid) ||
+ !bindIntParameter(xrefs_insert,":dst_rowid",dst_refid.rowid)
)
{
return false;
}
+ else
+ {
+ bindTextParameter(xrefs_insert,":context",context);
+ }
step(xrefs_insert);
return true;
}
-static void insertMemberReference(const MemberDef *src, const MemberDef *dst)
+static void insertMemberReference(const MemberDef *src, const MemberDef *dst, const char *context)
{
- QCString qrefid_dst = dst->getOutputFileBase() + "_1" + dst->anchor();
- QCString qrefid_src = src->getOutputFileBase() + "_1" + src->anchor();
- if (dst->getStartBodyLine()!=-1 && dst->getBodyDef())
- {
- int refid_src = insertRefid(qrefid_src.data());
- int refid_dst = insertRefid(qrefid_dst.data());
- int id_file = insertFile("no-file"); // TODO: replace no-file with proper file
- insertMemberReference(refid_src,refid_dst,id_file,dst->getStartBodyLine(),-1);
- }
+ QCString qdst_refid = dst->getOutputFileBase() + "_1" + dst->anchor();
+ QCString qsrc_refid = src->getOutputFileBase() + "_1" + src->anchor();
+
+ struct Refid src_refid = insertRefid(qsrc_refid);
+ struct Refid dst_refid = insertRefid(qdst_refid);
+ insertMemberReference(src_refid,dst_refid,context);
}
-static void insertMemberFunctionParams(int id_memberdef, const MemberDef *md, const Definition *def)
+static void insertMemberFunctionParams(int memberdef_id, const MemberDef *md, const Definition *def)
{
ArgumentList *declAl = md->declArgumentList();
ArgumentList *defAl = md->argumentList();
@@ -600,8 +1028,8 @@ static void insertMemberFunctionParams(int id_memberdef, const MemberDef *md, co
if (!a->attrib.isEmpty())
{
- bindTextParameter(params_select,":attributes",a->attrib.data());
- bindTextParameter(params_insert,":attributes",a->attrib.data());
+ bindTextParameter(param_select,":attributes",a->attrib);
+ bindTextParameter(param_insert,":attributes",a->attrib);
}
if (!a->type.isEmpty())
{
@@ -612,57 +1040,56 @@ static void insertMemberFunctionParams(int id_memberdef, const MemberDef *md, co
QCString *s;
while ((s=li.current()))
{
- QCString qrefid_src = md->getOutputFileBase() + "_1" + md->anchor();
- int refid_src = insertRefid(qrefid_src.data());
- int refid_dst = insertRefid(s->data());
- int id_file = insertFile(stripFromPath(def->getDefFileName()));
- insertMemberReference(refid_src,refid_dst,id_file,md->getDefLine(),-1);
+ QCString qsrc_refid = md->getOutputFileBase() + "_1" + md->anchor();
+ struct Refid src_refid = insertRefid(qsrc_refid);
+ struct Refid dst_refid = insertRefid(s->data());
+ insertMemberReference(src_refid,dst_refid, "argument");
++li;
}
- bindTextParameter(params_select,":type",a->type.data());
- bindTextParameter(params_insert,":type",a->type.data());
+ bindTextParameter(param_select,":type",a->type);
+ bindTextParameter(param_insert,":type",a->type);
}
if (!a->name.isEmpty())
{
- bindTextParameter(params_select,":declname",a->name.data());
- bindTextParameter(params_insert,":declname",a->name.data());
+ bindTextParameter(param_select,":declname",a->name);
+ bindTextParameter(param_insert,":declname",a->name);
}
if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
{
- bindTextParameter(params_select,":defname",defArg->name.data());
- bindTextParameter(params_insert,":defname",defArg->name.data());
+ bindTextParameter(param_select,":defname",defArg->name);
+ bindTextParameter(param_insert,":defname",defArg->name);
}
if (!a->array.isEmpty())
{
- bindTextParameter(params_select,":array",a->array.data());
- bindTextParameter(params_insert,":array",a->array.data());
+ bindTextParameter(param_select,":array",a->array);
+ bindTextParameter(param_insert,":array",a->array);
}
if (!a->defval.isEmpty())
{
StringList l;
linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,a->defval);
- bindTextParameter(params_select,":defval",a->defval.data());
- bindTextParameter(params_insert,":defval",a->defval.data());
+ bindTextParameter(param_select,":defval",a->defval);
+ bindTextParameter(param_insert,":defval",a->defval);
}
if (defArg) ++defAli;
- int id_param=step(params_select,TRUE,TRUE);
- if (id_param==0) {
- id_param=step(params_insert,TRUE);
+ int param_id=step(param_select,TRUE,TRUE);
+ if (param_id==0) {
+ param_id=step(param_insert,TRUE);
}
- if (id_param==-1) {
- msg("error INSERT params failed\n");
+ if (param_id==-1) {
+ DBG_CTX(("error INSERT params failed\n"));
continue;
}
- bindIntParameter(memberdef_params_insert,":id_memberdef",id_memberdef);
- bindIntParameter(memberdef_params_insert,":id_param",id_param);
- step(memberdef_params_insert);
+ bindIntParameter(memberdef_param_insert,":memberdef_id",memberdef_id);
+ bindIntParameter(memberdef_param_insert,":param_id",param_id);
+ step(memberdef_param_insert);
}
}
}
-static void insertMemberDefineParams(int id_memberdef,const MemberDef *md, const Definition *def)
+static void insertMemberDefineParams(int memberdef_id,const MemberDef *md, const Definition *def)
{
if (md->argumentList()->count()==0) // special case for "foo()" to
// disguish it from "foo".
@@ -675,20 +1102,34 @@ static void insertMemberDefineParams(int id_memberdef,const MemberDef *md, const
Argument *a;
for (ali.toFirst();(a=ali.current());++ali)
{
- bindTextParameter(params_insert,":defname",a->type.data());
- int id_param=step(params_insert,TRUE);
- if (id_param==-1) {
- msg("error INSERT param(%s) failed\n", a->type.data());
+ bindTextParameter(param_insert,":defname",a->type);
+ int param_id=step(param_insert,TRUE);
+ if (param_id==-1) {
continue;
}
- bindIntParameter(memberdef_params_insert,":id_memberdef",id_memberdef);
- bindIntParameter(memberdef_params_insert,":id_param",id_param);
- step(memberdef_params_insert);
+ bindIntParameter(memberdef_param_insert,":memberdef_id",memberdef_id);
+ bindIntParameter(memberdef_param_insert,":param_id",param_id);
+ step(memberdef_param_insert);
}
}
}
+static void associateMember(const MemberDef *md, struct Refid member_refid, struct Refid scope_refid)
+{
+ // TODO: skip EnumValue only to guard against recording refids and member records
+ // for enumvalues until we can support documenting them as entities.
+ if (md->memberType()==MemberType_EnumValue) return;
+ if (md->name().at(0)!='@') // skip anonymous members
+ {
+ bindIntParameter(member_insert, ":scope_rowid", scope_refid.rowid);
+ bindIntParameter(member_insert, ":memberdef_rowid", member_refid.rowid);
+
+ bindIntParameter(member_insert, ":prot", md->protection());
+ bindIntParameter(member_insert, ":virt", md->virtualness());
+ step(member_insert);
+ }
+}
static void stripQualifiers(QCString &typeStr)
{
@@ -720,22 +1161,28 @@ static int prepareStatement(sqlite3 *db, SqlStmt &s)
static int prepareStatements(sqlite3 *db)
{
if (
+ -1==prepareStatement(db, meta_insert) ||
+ -1==prepareStatement(db, memberdef_exists) ||
+ -1==prepareStatement(db, memberdef_incomplete) ||
-1==prepareStatement(db, memberdef_insert) ||
- -1==prepareStatement(db, files_insert) ||
- -1==prepareStatement(db, files_select) ||
- -1==prepareStatement(db, refids_insert) ||
- -1==prepareStatement(db, refids_select) ||
+ -1==prepareStatement(db, memberdef_update_def) ||
+ -1==prepareStatement(db, memberdef_update_decl) ||
+ -1==prepareStatement(db, member_insert) ||
+ -1==prepareStatement(db, path_insert) ||
+ -1==prepareStatement(db, path_select) ||
+ -1==prepareStatement(db, refid_insert) ||
+ -1==prepareStatement(db, refid_select) ||
-1==prepareStatement(db, incl_insert)||
-1==prepareStatement(db, incl_select)||
- -1==prepareStatement(db, params_insert) ||
- -1==prepareStatement(db, params_select) ||
+ -1==prepareStatement(db, param_insert) ||
+ -1==prepareStatement(db, param_select) ||
-1==prepareStatement(db, xrefs_insert) ||
- -1==prepareStatement(db, innerclass_insert) ||
+ -1==prepareStatement(db, reimplements_insert) ||
+ -1==prepareStatement(db, contains_insert) ||
+ -1==prepareStatement(db, compounddef_exists) ||
-1==prepareStatement(db, compounddef_insert) ||
- -1==prepareStatement(db, basecompoundref_insert) ||
- -1==prepareStatement(db, derivedcompoundref_insert) ||
- -1==prepareStatement(db, memberdef_params_insert)||
- -1==prepareStatement(db, innernamespace_insert)
+ -1==prepareStatement(db, compoundref_insert) ||
+ -1==prepareStatement(db, memberdef_param_insert)
)
{
return -1;
@@ -763,15 +1210,35 @@ static void pragmaTuning(sqlite3 *db)
sqlite3_exec(db, "PRAGMA temp_store = MEMORY;", NULL, NULL, &sErrMsg);
}
-static int initializeSchema(sqlite3* db)
+static int initializeTables(sqlite3* db)
+{
+ int rc;
+ sqlite3_stmt *stmt = 0;
+
+ msg("Initializing DB schema (tables)...\n");
+ for (unsigned int k = 0; k < sizeof(table_schema) / sizeof(table_schema[0]); k++)
+ {
+ const char *q = table_schema[k][1];
+ char *errmsg;
+ rc = sqlite3_exec(db, q, NULL, NULL, &errmsg);
+ if (rc != SQLITE_OK)
+ {
+ msg("failed to execute query: %s\n\t%s\n", q, errmsg);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int initializeViews(sqlite3* db)
{
int rc;
sqlite3_stmt *stmt = 0;
- msg("Initializing DB schema...\n");
- for (unsigned int k = 0; k < sizeof(schema_queries) / sizeof(schema_queries[0]); k++)
+ msg("Initializing DB schema (views)...\n");
+ for (unsigned int k = 0; k < sizeof(view_schema) / sizeof(view_schema[0]); k++)
{
- const char *q = schema_queries[k][1];
+ const char *q = view_schema[k][1];
char *errmsg;
rc = sqlite3_exec(db, q, NULL, NULL, &errmsg);
if (rc != SQLITE_OK)
@@ -784,40 +1251,122 @@ static int initializeSchema(sqlite3* db)
}
////////////////////////////////////////////
-static void writeInnerClasses(const ClassSDict *cl)
+/* TODO:
+I collapsed all innerX tables into 'contains', which raises the prospect that
+all of these very similar writeInnerX funcs could be refactored into a one,
+or a small set of common parts.
+
+I think the hurdles are:
+- picking a first argument that every call location can pass
+- which yields a consistent iterator
+- accommodates PageDef's slightly different rules for generating the
+ inner_refid (unless I'm missing a method that would uniformly return
+ the correct refid for all types).
+*/
+static void writeInnerClasses(const ClassSDict *cl, struct Refid outer_refid)
{
if (!cl) return;
ClassSDict::Iterator cli(*cl);
- ClassDef *cd;
+ const ClassDef *cd;
for (cli.toFirst();(cd=cli.current());++cli)
{
if (!cd->isHidden() && cd->name().find('@')==-1) // skip anonymous scopes
{
- int refid = insertRefid(cd->getOutputFileBase());
- bindIntParameter(innerclass_insert,":refid", refid);
- bindIntParameter(innerclass_insert,":prot",cd->protection());
- bindTextParameter(innerclass_insert,":name",cd->name());
- step(innerclass_insert);
+ struct Refid inner_refid = insertRefid(cd->getOutputFileBase());
+
+ bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid);
+ bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid);
+ step(contains_insert);
}
}
}
+static void writeInnerPages(const PageSDict *pl, struct Refid outer_refid)
+{
+ if (!pl) return;
+
+ PageSDict::Iterator pli(*pl);
+ const PageDef *pd;
+ for (pli.toFirst();(pd=pli.current());++pli)
+ {
+ struct Refid inner_refid = insertRefid(
+ pd->getGroupDef() ? pd->getOutputFileBase()+"_"+pd->name() : pd->getOutputFileBase()
+ );
+
+ bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid);
+ bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid);
+ step(contains_insert);
-static void writeInnerNamespaces(const NamespaceSDict *nl)
+ }
+}
+
+static void writeInnerGroups(const GroupList *gl, struct Refid outer_refid)
+{
+ if (gl)
+ {
+ GroupListIterator gli(*gl);
+ const GroupDef *sgd;
+ for (gli.toFirst();(sgd=gli.current());++gli)
+ {
+ struct Refid inner_refid = insertRefid(sgd->getOutputFileBase());
+
+ bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid);
+ bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid);
+ step(contains_insert);
+ }
+ }
+}
+
+static void writeInnerFiles(const FileList *fl, struct Refid outer_refid)
+{
+ if (fl)
+ {
+ QListIterator<FileDef> fli(*fl);
+ const FileDef *fd;
+ for (fli.toFirst();(fd=fli.current());++fli)
+ {
+ struct Refid inner_refid = insertRefid(fd->getOutputFileBase());
+
+ bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid);
+ bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid);
+ step(contains_insert);
+ }
+ }
+}
+
+static void writeInnerDirs(const DirList *dl, struct Refid outer_refid)
+{
+ if (dl)
+ {
+ QListIterator<DirDef> subdirs(*dl);
+ const DirDef *subdir;
+ for (subdirs.toFirst();(subdir=subdirs.current());++subdirs)
+ {
+ struct Refid inner_refid = insertRefid(subdir->getOutputFileBase());
+
+ bindIntParameter(contains_insert,":inner_rowid", inner_refid.rowid);
+ bindIntParameter(contains_insert,":outer_rowid", outer_refid.rowid);
+ step(contains_insert);
+ }
+ }
+}
+
+static void writeInnerNamespaces(const NamespaceSDict *nl, struct Refid outer_refid)
{
if (nl)
{
NamespaceSDict::Iterator nli(*nl);
- NamespaceDef *nd;
+ const NamespaceDef *nd;
for (nli.toFirst();(nd=nli.current());++nli)
{
- if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes
+ if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymous scopes
{
- int refid = insertRefid(nd->getOutputFileBase());
- bindIntParameter(innernamespace_insert,":refid",refid);
- bindTextParameter(innernamespace_insert,":name",nd->name(),FALSE);
- step(innernamespace_insert);
+ struct Refid inner_refid = insertRefid(nd->getOutputFileBase());
+
+ bindIntParameter(contains_insert,":inner_rowid",inner_refid.rowid);
+ bindIntParameter(contains_insert,":outer_rowid",outer_refid.rowid);
+ step(contains_insert);
}
}
}
@@ -837,24 +1386,24 @@ static void writeTemplateArgumentList(const ArgumentList * al,
if (!a->type.isEmpty())
{
#warning linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->type);
- bindTextParameter(params_select,":type",a->type);
- bindTextParameter(params_insert,":type",a->type);
+ bindTextParameter(param_select,":type",a->type);
+ bindTextParameter(param_insert,":type",a->type);
}
if (!a->name.isEmpty())
{
- bindTextParameter(params_select,":declname",a->name);
- bindTextParameter(params_insert,":declname",a->name);
- bindTextParameter(params_select,":defname",a->name);
- bindTextParameter(params_insert,":defname",a->name);
+ bindTextParameter(param_select,":declname",a->name);
+ bindTextParameter(param_insert,":declname",a->name);
+ bindTextParameter(param_select,":defname",a->name);
+ bindTextParameter(param_insert,":defname",a->name);
}
if (!a->defval.isEmpty())
{
#warning linkifyText(TextGeneratorXMLImpl(t),scope,fileScope,0,a->defval);
- bindTextParameter(params_select,":defval",a->defval);
- bindTextParameter(params_insert,":defval",a->defval);
+ bindTextParameter(param_select,":defval",a->defval);
+ bindTextParameter(param_insert,":defval",a->defval);
}
- if (!step(params_select,TRUE,TRUE))
- step(params_insert);
+ if (!step(param_select,TRUE,TRUE))
+ step(param_insert);
}
}
}
@@ -871,15 +1420,132 @@ static void writeTemplateList(const ClassDef *cd)
{
writeTemplateArgumentList(cd->templateArguments(),cd,0);
}
+
+QCString getSQLDocBlock(const Definition *scope,
+ const Definition *def,
+ const QCString &doc,
+ const QCString &fileName,
+ int lineNr)
+{
+ QGString s;
+ if (doc.isEmpty()) return s.data();
+ FTextStream t(&s);
+ DocNode *root = validatingParseDoc(
+ fileName,
+ lineNr,
+ const_cast<Definition*>(scope),
+ const_cast<MemberDef*>(reinterpret_cast<const MemberDef*>(def)),
+ doc,
+ FALSE,
+ FALSE
+ );
+ XMLCodeGenerator codeGen(t);
+ // create a parse tree visitor for XML
+ XmlDocVisitor *visitor = new XmlDocVisitor(t,codeGen);
+ root->accept(visitor);
+ delete visitor;
+ delete root;
+ QCString result = convertCharEntitiesToUTF8(s.data());
+ return result.data();
+}
+
+static void getSQLDesc(SqlStmt &s,const char *col,const char *value,const Definition *def)
+{
+ bindTextParameter(
+ s,
+ col,
+ getSQLDocBlock(
+ def->getOuterScope(),
+ def,
+ value,
+ def->docFile(),
+ def->docLine()
+ ),
+ FALSE
+ );
+}
////////////////////////////////////////////
+/* (updated Sep 01 2018)
+DoxMemberKind and DoxCompoundKind (compound.xsd) gave me some
+faulty assumptions about "kind" strings, so I compiled a reference
+
+The XML schema claims:
+ DoxMemberKind: (14)
+ dcop define enum event friend function interface property prototype
+ service signal slot typedef variable
+
+ DoxCompoundKind: (17)
+ category class dir example exception file group interface module
+ namespace page protocol service singleton struct type union
+
+Member kind comes from MemberDef::memberTypeName()
+ types.h defines 14 MemberType_*s
+ _DCOP _Define _Enumeration _EnumValue _Event _Friend _Function _Interface
+ _Property _Service _Signal _Slot _Typedef _Variable
+ - xml doesn't include enumvalue here
+ (but renders enumvalue as) a sub-node of memberdef/templateparamlist
+ - xml includes 'prototype' that is unlisted here
+ vestigial? commented out in docsets.cpp and perlmodgen.cpp
+ MemberDef::memberTypeName() can return 15 strings:
+ (sorted by MemberType to match above; quoted because whitespace...)
+ "dcop" "macro definition" "enumeration" "enumvalue" "event" "friend"
+ "function" "interface" "property" "service" "signal" "slot" "typedef"
+ "variable"
+
+ Above describes potential values for memberdef.kind
+
+Compound kind is more complex. *Def::compoundTypeString()
+ ClassDef kind comes from ::compoundTypeString()
+ classdef.h defines 9 compound types
+ Category Class Exception Interface Protocol Service Singleton Struct Union
+ But ClassDef::compoundTypeString() "could" return 13 strings
+ - default "unknown" shouldn't actually return
+ - other 12 can vary by source language; see method for specifics
+ category class enum exception interface module protocol service
+ singleton struct type union
+
+ DirDef, FileDef, GroupDef have no method to return a string
+ tagfile/outputs hard-code kind to 'dir' 'file' or 'group'
+
+ NamespaceDef kind comes from ::compoundTypeString()
+ NamespaceDef::compoundTypeString() "could" return 6 strings
+ - default empty ("") string
+ - other 5 differ by source language
+ constants library module namespace package
+
+ PageDef also has no method to return a string
+ - some locations hard-code the kind to 'page'
+ - others conditionally output 'page' or 'example'
+
+ All together, that's 23 potential strings (21 excl "" and unknown)
+ "" category class constants dir enum example exception file group
+ interface library module namespace package page protocol service singleton
+ struct type union unknown
+
+ Above describes potential values for compounddef.kind
+
+For reference, there are 35 potential values of def.kind (33 excl "" and unknown):
+ "" "category" "class" "constants" "dcop" "dir" "enum" "enumeration"
+ "enumvalue" "event" "example" "exception" "file" "friend" "function" "group"
+ "interface" "library" "macro definition" "module" "namespace" "package"
+ "page" "property" "protocol" "service" "signal" "singleton" "slot" "struct"
+ "type" "typedef" "union" "unknown" "variable"
+
+This is relevant because the 'def' view generalizes memberdef and compounddef,
+and two member+compound kind strings (interface and service) overlap.
+
+I have no grasp of whether a real user docset would include one or more
+member and compound using the interface or service kind.
+*/
+
//////////////////////////////////////////////////////////////////////////////
-static void generateSqlite3ForMember(const MemberDef *md, const Definition *def)
+static void generateSqlite3ForMember(const MemberDef *md, struct Refid scope_refid, const Definition *def)
{
// + declaration/definition arg lists
// + reimplements
// + reimplementedBy
- // + exceptions
+ // - exceptions
// + const/volatile specifiers
// - examples
// + source definition
@@ -893,18 +1559,102 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def)
// enum values are written as part of the enum
if (md->memberType()==MemberType_EnumValue) return;
if (md->isHidden()) return;
- //if (md->name().at(0)=='@') return; // anonymous member
- // group members are only visible in their group
- //if (def->definitionType()!=Definition::TypeGroup && md->getGroupDef()) return;
QCString memType;
// memberdef
QCString qrefid = md->getOutputFileBase() + "_1" + md->anchor();
- int refid = insertRefid(qrefid.data());
+ struct Refid refid = insertRefid(qrefid);
+
+ associateMember(md, refid, scope_refid);
+
+ // compacting duplicate defs
+ if(!refid.created && memberdefExists(refid) && memberdefIncomplete(refid, md))
+ {
+ /*
+ For performance, ideal to skip a member we've already added.
+ Unfortunately, we can have two memberdefs with the same refid documenting
+ the declaration and definition. memberdefIncomplete() uses the 'inline'
+ value to figure this out. Once we get to this point, we should *only* be
+ seeing the *other* type of def/decl, so we'll set inline to a new value (2),
+ indicating that this entry covers both inline types.
+ */
+ struct SqlStmt memberdef_update;
+
+ // definitions have bodyfile/start/end
+ if (md->getStartBodyLine()!=-1)
+ {
+ memberdef_update = memberdef_update_def;
+ int bodyfile_id = insertPath(md->getBodyDef()->absFilePath(),!md->getBodyDef()->isReference());
+ if (bodyfile_id == -1)
+ {
+ sqlite3_clear_bindings(memberdef_update.stmt);
+ }
+ else
+ {
+ bindIntParameter(memberdef_update,":bodyfile_id",bodyfile_id);
+ bindIntParameter(memberdef_update,":bodystart",md->getStartBodyLine());
+ bindIntParameter(memberdef_update,":bodyend",md->getEndBodyLine());
+ }
+ }
+ // declarations don't
+ else
+ {
+ memberdef_update = memberdef_update_decl;
+ if (md->getDefLine() != -1)
+ {
+ int file_id = insertPath(md->getDefFileName(),!md->isReference());
+ if (file_id!=-1)
+ {
+ bindIntParameter(memberdef_update,":file_id",file_id);
+ bindIntParameter(memberdef_update,":line",md->getDefLine());
+ bindIntParameter(memberdef_update,":column",md->getDefColumn());
+ }
+ }
+ }
- bindIntParameter(memberdef_insert,":refid", refid);
- bindIntParameter(memberdef_insert,":kind",md->memberType());
+ bindIntParameter(memberdef_update, ":rowid", refid.rowid);
+ // value 2 indicates we've seen "both" inline types.
+ bindIntParameter(memberdef_update,":inline", 2);
+
+ /* in case both are used, append/prepend descriptions */
+ getSQLDesc(memberdef_update,":briefdescription",md->briefDescription(),md);
+ getSQLDesc(memberdef_update,":detaileddescription",md->documentation(),md);
+ getSQLDesc(memberdef_update,":inbodydescription",md->inbodyDocumentation(),md);
+
+ step(memberdef_update,TRUE);
+
+ // don't think we need to repeat params; should have from first encounter
+
+ // + source references
+ // The cross-references in initializers only work when both the src and dst
+ // are defined.
+ MemberSDict *mdict = md->getReferencesMembers();
+ if (mdict!=0)
+ {
+ MemberSDict::IteratorDict mdi(*mdict);
+ const MemberDef *rmd;
+ for (mdi.toFirst();(rmd=mdi.current());++mdi)
+ {
+ insertMemberReference(md,rmd, "inline");
+ }
+ }
+ // + source referenced by
+ mdict = md->getReferencedByMembers();
+ if (mdict!=0)
+ {
+ MemberSDict::IteratorDict mdi(*mdict);
+ const MemberDef *rmd;
+ for (mdi.toFirst();(rmd=mdi.current());++mdi)
+ {
+ insertMemberReference(rmd,md, "inline");
+ }
+ }
+ return;
+ }
+
+ bindIntParameter(memberdef_insert,":rowid", refid.rowid);
+ bindTextParameter(memberdef_insert,":kind",md->memberTypeName(),FALSE);
bindIntParameter(memberdef_insert,":prot",md->protection());
bindIntParameter(memberdef_insert,":static",md->isStatic());
@@ -973,6 +1723,7 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def)
bindIntParameter(memberdef_insert,":settable",md->isSettable());
bindIntParameter(memberdef_insert,":privatesettable",md->isPrivateSettable());
bindIntParameter(memberdef_insert,":protectedsettable",md->isProtectedSettable());
+
if (md->isAssign() || md->isCopy() || md->isRetain()
|| md->isStrong() || md->isWeak())
{
@@ -995,6 +1746,18 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def)
bindIntParameter(memberdef_insert,":raisable",md->isRaisable());
}
+ const MemberDef *rmd = md->reimplements();
+ if(rmd)
+ {
+ QCString qreimplemented_refid = rmd->getOutputFileBase() + "_1" + rmd->anchor();
+
+ struct Refid reimplemented_refid = insertRefid(qreimplemented_refid);
+
+ bindIntParameter(reimplements_insert,":memberdef_rowid", refid.rowid);
+ bindIntParameter(reimplements_insert,":reimplemented_rowid", reimplemented_refid.rowid);
+ step(reimplements_insert,TRUE);
+ }
+
// + declaration/definition arg lists
if (md->memberType()!=MemberType_Define &&
md->memberType()!=MemberType_Enumeration
@@ -1008,9 +1771,9 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def)
stripQualifiers(typeStr);
StringList l;
linkifyText(TextGeneratorSqlite3Impl(l), def, md->getBodyDef(),md,typeStr);
- if (typeStr.data())
+ if (typeStr)
{
- bindTextParameter(memberdef_insert,":type",typeStr.data(),FALSE);
+ bindTextParameter(memberdef_insert,":type",typeStr,FALSE);
}
if (md->definition())
@@ -1029,7 +1792,7 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def)
// Extract references from initializer
if (md->hasMultiLineInitializer() || md->hasOneLineInitializer())
{
- bindTextParameter(memberdef_insert,":initializer",md->initializer().data());
+ bindTextParameter(memberdef_insert,":initializer",md->initializer());
StringList l;
linkifyText(TextGeneratorSqlite3Impl(l),def,md->getBodyDef(),md,md->initializer());
@@ -1044,11 +1807,10 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def)
s->data(),
md->getBodyDef()->getDefFileName().data(),
md->getStartBodyLine()));
- QCString qrefid_src = md->getOutputFileBase() + "_1" + md->anchor();
- int refid_src = insertRefid(qrefid_src.data());
- int refid_dst = insertRefid(s->data());
- int id_file = insertFile(stripFromPath(md->getBodyDef()->getDefFileName()));
- insertMemberReference(refid_src,refid_dst,id_file,md->getStartBodyLine(),-1);
+ QCString qsrc_refid = md->getOutputFileBase() + "_1" + md->anchor();
+ struct Refid src_refid = insertRefid(qsrc_refid);
+ struct Refid dst_refid = insertRefid(s->data());
+ insertMemberReference(src_refid,dst_refid, "initializer");
}
++li;
}
@@ -1056,34 +1818,35 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def)
if ( md->getScopeString() )
{
- bindTextParameter(memberdef_insert,":scope",md->getScopeString().data(),FALSE);
+ bindTextParameter(memberdef_insert,":scope",md->getScopeString(),FALSE);
}
// +Brief, detailed and inbody description
- bindTextParameter(memberdef_insert,":briefdescription",md->briefDescription(),FALSE);
- bindTextParameter(memberdef_insert,":detaileddescription",md->documentation(),FALSE);
- bindTextParameter(memberdef_insert,":inbodydescription",md->inbodyDocumentation(),FALSE);
+ getSQLDesc(memberdef_insert,":briefdescription",md->briefDescription(),md);
+ getSQLDesc(memberdef_insert,":detaileddescription",md->documentation(),md);
+ getSQLDesc(memberdef_insert,":inbodydescription",md->inbodyDocumentation(),md);
// File location
if (md->getDefLine() != -1)
{
- int id_file = insertFile(stripFromPath(md->getDefFileName()));
- if (id_file!=-1)
+ int file_id = insertPath(md->getDefFileName(),!md->isReference());
+ if (file_id!=-1)
{
- bindIntParameter(memberdef_insert,":id_file",id_file);
+ bindIntParameter(memberdef_insert,":file_id",file_id);
bindIntParameter(memberdef_insert,":line",md->getDefLine());
bindIntParameter(memberdef_insert,":column",md->getDefColumn());
+ // definitions also have bodyfile/start/end
if (md->getStartBodyLine()!=-1)
{
- int id_bodyfile = insertFile(stripFromPath(md->getBodyDef()->absFilePath()));
- if (id_bodyfile == -1)
+ int bodyfile_id = insertPath(md->getBodyDef()->absFilePath(),!md->getBodyDef()->isReference());
+ if (bodyfile_id == -1)
{
sqlite3_clear_bindings(memberdef_insert.stmt);
}
else
{
- bindIntParameter(memberdef_insert,":id_bodyfile",id_bodyfile);
+ bindIntParameter(memberdef_insert,":bodyfile_id",bodyfile_id);
bindIntParameter(memberdef_insert,":bodystart",md->getStartBodyLine());
bindIntParameter(memberdef_insert,":bodyend",md->getEndBodyLine());
}
@@ -1091,16 +1854,16 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def)
}
}
- int id_memberdef=step(memberdef_insert,TRUE);
+ int memberdef_id=step(memberdef_insert,TRUE);
if (isFunc)
{
- insertMemberFunctionParams(id_memberdef,md,def);
+ insertMemberFunctionParams(memberdef_id,md,def);
}
else if (md->memberType()==MemberType_Define &&
md->argsString())
{
- insertMemberDefineParams(id_memberdef,md,def);
+ insertMemberDefineParams(memberdef_id,md,def);
}
// + source references
@@ -1110,10 +1873,10 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def)
if (mdict!=0)
{
MemberSDict::IteratorDict mdi(*mdict);
- MemberDef *rmd;
+ const MemberDef *rmd;
for (mdi.toFirst();(rmd=mdi.current());++mdi)
{
- insertMemberReference(md,rmd);//,mdi.currentKey());
+ insertMemberReference(md,rmd, "inline");
}
}
// + source referenced by
@@ -1121,62 +1884,79 @@ static void generateSqlite3ForMember(const MemberDef *md, const Definition *def)
if (mdict!=0)
{
MemberSDict::IteratorDict mdi(*mdict);
- MemberDef *rmd;
+ const MemberDef *rmd;
for (mdi.toFirst();(rmd=mdi.current());++mdi)
{
- insertMemberReference(rmd,md);//,mdi.currentKey());
+ insertMemberReference(rmd,md, "inline");
}
}
}
static void generateSqlite3Section( const Definition *d,
const MemberList *ml,
+ struct Refid scope_refid,
const char * /*kind*/,
const char * /*header*/=0,
const char * /*documentation*/=0)
{
if (ml==0) return;
MemberListIterator mli(*ml);
- MemberDef *md;
- int count=0;
+ const MemberDef *md;
+
for (mli.toFirst();(md=mli.current());++mli)
{
+ // TODO: necessary? just tracking what xmlgen does; xmlgen says:
// namespace members are also inserted in the file scope, but
// to prevent this duplication in the XML output, we filter those here.
if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
{
- count++;
+ generateSqlite3ForMember(md, scope_refid, d);
}
}
- if (count==0) return; // empty list
- for (mli.toFirst();(md=mli.current());++mli)
+}
+
+static void associateAllClassMembers(const ClassDef *cd, struct Refid scope_refid)
+{
+ if (cd->memberNameInfoSDict())
{
- // namespace members are also inserted in the file scope, but
- // to prevent this duplication in the XML output, we filter those here.
- //if (d->definitionType()!=Definition::TypeFile || md->getNamespaceDef()==0)
+ MemberNameInfoSDict::Iterator mnii(*cd->memberNameInfoSDict());
+ MemberNameInfo *mni;
+ for (mnii.toFirst();(mni=mnii.current());++mnii)
{
- generateSqlite3ForMember(md,d);
+ MemberNameInfoIterator mii(*mni);
+ MemberInfo *mi;
+ for (mii.toFirst();(mi=mii.current());++mii)
+ {
+ MemberDef *md = mi->memberDef;
+ QCString qrefid = md->getOutputFileBase() + "_1" + md->anchor();
+ associateMember(md, insertRefid(qrefid), scope_refid);
+ }
}
}
}
-
+// many kinds: category class enum exception interface
+// module protocol service singleton struct type union
+// enum is Java only (and is distinct from enum memberdefs)
static void generateSqlite3ForClass(const ClassDef *cd)
{
+ // NOTE: Skeptical about XML's version of these
+ // 'x' marks missing items XML claims to include
+
+ // + brief description
+ // + detailed description
+ // + template argument list(s)
+ // + include file
+ // + member groups
+ // x inheritance DOT diagram
// + list of direct super classes
// + list of direct sub classes
- // + include file
// + list of inner classes
- // - template argument list(s)
- // + member groups
+ // x collaboration DOT diagram
// + list of all members
- // - brief description
- // - detailed description
- // - inheritance DOT diagram
- // - collaboration DOT diagram
- // - user defined member sections
- // - standard member sections
- // - detailed member documentation
+ // x user defined member sections
+ // x standard member sections
+ // x detailed member documentation
// - examples using the class
if (cd->isReference()) return; // skip external references.
@@ -1184,43 +1964,86 @@ static void generateSqlite3ForClass(const ClassDef *cd)
if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
if (cd->templateMaster()!=0) return; // skip generated template instances.
- msg("Generating Sqlite3 output for class %s\n",cd->name().data());
+ struct Refid refid = insertRefid(cd->getOutputFileBase());
+
+ // can omit a class that already has a refid
+ if(!refid.created && compounddefExists(refid)){return;}
+
+ bindIntParameter(compounddef_insert,":rowid", refid.rowid);
bindTextParameter(compounddef_insert,":name",cd->name());
+ bindTextParameter(compounddef_insert,":title",cd->title(), FALSE);
bindTextParameter(compounddef_insert,":kind",cd->compoundTypeString(),FALSE);
bindIntParameter(compounddef_insert,":prot",cd->protection());
- int refid = insertRefid(cd->getOutputFileBase());
- bindIntParameter(compounddef_insert,":refid", refid);
- int id_file = insertFile(stripFromPath(cd->getDefFileName()));
- bindIntParameter(compounddef_insert,":id_file",id_file);
+ int file_id = insertPath(cd->getDefFileName());
+ bindIntParameter(compounddef_insert,":file_id",file_id);
bindIntParameter(compounddef_insert,":line",cd->getDefLine());
bindIntParameter(compounddef_insert,":column",cd->getDefColumn());
+ // + include file
+ /*
+ TODO: I wonder if this can actually be cut (just here)
+
+ We were adding this "include" to the "includes" table alongside
+ other includes (from a FileDef). However, FileDef and ClassDef are using
+ "includes" nodes in very a different way:
+ - With FileDef, it means the file includes another.
+ - With ClassDef, it means you should include this file to use this class.
+
+ Because of this difference, I added a column to compounddef, header_id, and
+ linked it back to the appropriate file. We could just add a nullable text
+ column that would hold a string equivalent to what the HTML docs include,
+ but the logic for generating it is embedded in
+ ClassDef::writeIncludeFiles(OutputList &ol).
+
+ That said, at least on the handful of test sets I have, header_id == file_id,
+ suggesting it could be cut and clients might be able to reconstruct it from
+ other values if there's a solid heuristic for *when a class will
+ have a header file*.
+ */
+ IncludeInfo *ii=cd->includeInfo();
+ if (ii)
+ {
+ QCString nm = ii->includeName;
+ if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
+ if (!nm.isEmpty())
+ {
+ int header_id=insertPath(ii->fileDef->absFilePath(),!ii->fileDef->isReference());
+ DBG_CTX(("-----> ClassDef includeInfo for %s\n", nm.data()));
+ DBG_CTX((" local : %d\n", ii->local));
+ DBG_CTX((" imported : %d\n", ii->imported));
+ DBG_CTX((" indirect : %d\n", ii->indirect));
+ DBG_CTX(("header: %s\n", ii->fileDef->absFilePath().data()));
+ DBG_CTX((" file_id : %d\n", file_id));
+ DBG_CTX((" header_id: %d\n", header_id));
+
+ if(header_id!=-1)
+ {
+ bindIntParameter(compounddef_insert,":header_id",header_id);
+ }
+ }
+ }
+
+ getSQLDesc(compounddef_insert,":briefdescription",cd->briefDescription(),cd);
+ getSQLDesc(compounddef_insert,":detaileddescription",cd->documentation(),cd);
+
step(compounddef_insert);
// + list of direct super classes
if (cd->baseClasses())
{
BaseClassListIterator bcli(*cd->baseClasses());
- BaseClassDef *bcd;
+ const BaseClassDef *bcd;
for (bcli.toFirst();(bcd=bcli.current());++bcli)
{
- int refid = insertRefid(bcd->classDef->getOutputFileBase());
- bindIntParameter(basecompoundref_insert,":refid", refid);
- bindIntParameter(basecompoundref_insert,":prot",bcd->prot);
- bindIntParameter(basecompoundref_insert,":virt",bcd->virt);
-
- if (!bcd->templSpecifiers.isEmpty())
- {
- bindTextParameter(basecompoundref_insert,":base",insertTemplateSpecifierInScope(bcd->classDef->name(),bcd->templSpecifiers),FALSE);
- }
- else
- {
- bindTextParameter(basecompoundref_insert,":base",bcd->classDef->displayName(),FALSE);
- }
- bindTextParameter(basecompoundref_insert,":derived",cd->displayName(),FALSE);
- step(basecompoundref_insert);
+ struct Refid base_refid = insertRefid(bcd->classDef->getOutputFileBase());
+ struct Refid derived_refid = insertRefid(cd->getOutputFileBase());
+ bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid);
+ bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid);
+ bindIntParameter(compoundref_insert,":prot",bcd->prot);
+ bindIntParameter(compoundref_insert,":virt",bcd->virt);
+ step(compoundref_insert);
}
}
@@ -1228,54 +2051,23 @@ static void generateSqlite3ForClass(const ClassDef *cd)
if (cd->subClasses())
{
BaseClassListIterator bcli(*cd->subClasses());
- BaseClassDef *bcd;
+ const BaseClassDef *bcd;
for (bcli.toFirst();(bcd=bcli.current());++bcli)
{
- bindTextParameter(derivedcompoundref_insert,":base",cd->displayName(),FALSE);
- if (!bcd->templSpecifiers.isEmpty())
- {
- bindTextParameter(derivedcompoundref_insert,":derived",insertTemplateSpecifierInScope(bcd->classDef->name(),bcd->templSpecifiers),FALSE);
- }
- else
- {
- bindTextParameter(derivedcompoundref_insert,":derived",bcd->classDef->displayName(),FALSE);
- }
- int refid = insertRefid(bcd->classDef->getOutputFileBase());
- bindIntParameter(derivedcompoundref_insert,":refid", refid);
- bindIntParameter(derivedcompoundref_insert,":prot",bcd->prot);
- bindIntParameter(derivedcompoundref_insert,":virt",bcd->virt);
- step(derivedcompoundref_insert);
+ struct Refid derived_refid = insertRefid(bcd->classDef->getOutputFileBase());
+ struct Refid base_refid = insertRefid(cd->getOutputFileBase());
+ bindIntParameter(compoundref_insert,":base_rowid", base_refid.rowid);
+ bindIntParameter(compoundref_insert,":derived_rowid", derived_refid.rowid);
+ bindIntParameter(compoundref_insert,":prot",bcd->prot);
+ bindIntParameter(compoundref_insert,":virt",bcd->virt);
+ step(compoundref_insert);
}
}
- // + include file
- IncludeInfo *ii=cd->includeInfo();
- if (ii)
- {
- QCString nm = ii->includeName;
- if (nm.isEmpty() && ii->fileDef) nm = ii->fileDef->docName();
- if (!nm.isEmpty())
- {
- int id_dst=insertFile(nm);
- if (id_dst!=-1) {
- bindIntParameter(incl_select,":local",ii->local);
- bindIntParameter(incl_select,":id_src",id_file);
- bindIntParameter(incl_select,":id_dst",id_dst);
- int count=step(incl_select,TRUE,TRUE);
- if (count==0)
- {
- bindIntParameter(incl_insert,":local",ii->local);
- bindIntParameter(incl_insert,":id_src",id_file);
- bindIntParameter(incl_insert,":id_dst",id_dst);
- step(incl_insert);
- }
- }
- }
- }
// + list of inner classes
- writeInnerClasses(cd->getClassSDict());
+ writeInnerClasses(cd->getClassSDict(),refid);
- // - template argument list(s)
+ // + template argument list(s)
writeTemplateList(cd);
// + member groups
@@ -1285,41 +2077,62 @@ static void generateSqlite3ForClass(const ClassDef *cd)
MemberGroup *mg;
for (;(mg=mgli.current());++mgli)
{
- generateSqlite3Section(cd,mg->members(),"user-defined",mg->header(),
+ generateSqlite3Section(cd,mg->members(),refid,"user-defined",mg->header(),
mg->documentation());
}
}
- // + list of all members
+ // this is just a list of *local* members
QListIterator<MemberList> mli(cd->getMemberLists());
MemberList *ml;
for (mli.toFirst();(ml=mli.current());++mli)
{
if ((ml->listType()&MemberListType_detailedLists)==0)
{
- generateSqlite3Section(cd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType()));
+ generateSqlite3Section(cd,ml,refid,"user-defined");
}
}
+
+ // + list of all members
+ associateAllClassMembers(cd, refid);
}
+// kinds: constants library module namespace package
static void generateSqlite3ForNamespace(const NamespaceDef *nd)
{
// + contained class definitions
// + contained namespace definitions
// + member groups
// + normal members
- // - brief desc
- // - detailed desc
- // - location
+ // + brief desc
+ // + detailed desc
+ // + location (file_id, line, column)
// - files containing (parts of) the namespace definition
if (nd->isReference() || nd->isHidden()) return; // skip external references
+ struct Refid refid = insertRefid(nd->getOutputFileBase());
+ if(!refid.created && compounddefExists(refid)){return;}
+ bindIntParameter(compounddef_insert,":rowid", refid.rowid);
+
+ bindTextParameter(compounddef_insert,":name",nd->name());
+ bindTextParameter(compounddef_insert,":title",nd->title(), FALSE);
+ bindTextParameter(compounddef_insert,":kind","namespace",FALSE);
+
+ int file_id = insertPath(nd->getDefFileName());
+ bindIntParameter(compounddef_insert,":file_id",file_id);
+ bindIntParameter(compounddef_insert,":line",nd->getDefLine());
+ bindIntParameter(compounddef_insert,":column",nd->getDefColumn());
+
+ getSQLDesc(compounddef_insert,":briefdescription",nd->briefDescription(),nd);
+ getSQLDesc(compounddef_insert,":detaileddescription",nd->documentation(),nd);
+
+ step(compounddef_insert);
// + contained class definitions
- writeInnerClasses(nd->getClassSDict());
+ writeInnerClasses(nd->getClassSDict(),refid);
// + contained namespace definitions
- writeInnerNamespaces(nd->getNamespaceSDict());
+ writeInnerNamespaces(nd->getNamespaceSDict(),refid);
// + member groups
if (nd->getMemberGroupSDict())
@@ -1328,7 +2141,7 @@ static void generateSqlite3ForNamespace(const NamespaceDef *nd)
MemberGroup *mg;
for (;(mg=mgli.current());++mgli)
{
- generateSqlite3Section(nd,mg->members(),"user-defined",mg->header(),
+ generateSqlite3Section(nd,mg->members(),refid,"user-defined",mg->header(),
mg->documentation());
}
}
@@ -1340,29 +2153,48 @@ static void generateSqlite3ForNamespace(const NamespaceDef *nd)
{
if ((ml->listType()&MemberListType_declarationLists)!=0)
{
- generateSqlite3Section(nd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType()));
+ generateSqlite3Section(nd,ml,refid,"user-defined");
}
}
}
+// kind: file
static void generateSqlite3ForFile(const FileDef *fd)
{
// + includes files
// + includedby files
- // - include graph
- // - included by graph
+ // x include graph
+ // x included by graph
// + contained class definitions
// + contained namespace definitions
// + member groups
// + normal members
- // - brief desc
- // - detailed desc
- // - source code
- // - location
+ // + brief desc
+ // + detailed desc
+ // x source code
+ // + location (file_id, line, column)
// - number of lines
if (fd->isReference()) return; // skip external references
+ struct Refid refid = insertRefid(fd->getOutputFileBase());
+ if(!refid.created && compounddefExists(refid)){return;}
+ bindIntParameter(compounddef_insert,":rowid", refid.rowid);
+
+ bindTextParameter(compounddef_insert,":name",fd->name(),FALSE);
+ bindTextParameter(compounddef_insert,":title",fd->title(),FALSE);
+ bindTextParameter(compounddef_insert,":kind","file",FALSE);
+
+ int file_id = insertPath(fd->getDefFileName());
+ bindIntParameter(compounddef_insert,":file_id",file_id);
+ bindIntParameter(compounddef_insert,":line",fd->getDefLine());
+ bindIntParameter(compounddef_insert,":column",fd->getDefColumn());
+
+ getSQLDesc(compounddef_insert,":briefdescription",fd->briefDescription(),fd);
+ getSQLDesc(compounddef_insert,":detaileddescription",fd->documentation(),fd);
+
+ step(compounddef_insert);
+
// + includes files
IncludeInfo *ii;
if (fd->includeFileList())
@@ -1370,15 +2202,48 @@ static void generateSqlite3ForFile(const FileDef *fd)
QListIterator<IncludeInfo> ili(*fd->includeFileList());
for (ili.toFirst();(ii=ili.current());++ili)
{
- int id_src=insertFile(fd->absFilePath().data());
- int id_dst=insertFile(ii->includeName.data());
+ int src_id=insertPath(fd->absFilePath(),!fd->isReference());
+ int dst_id;
+ QCString dst_path;
+
+ if(ii->fileDef) // found file
+ {
+ if(ii->fileDef->isReference())
+ {
+ // strip tagfile from path
+ QCString tagfile = ii->fileDef->getReference();
+ dst_path = ii->fileDef->absFilePath().copy();
+ dst_path.stripPrefix(tagfile+":");
+ }
+ else
+ {
+ dst_path = ii->fileDef->absFilePath();
+ }
+ dst_id = insertPath(dst_path,ii->local);
+ }
+ else // can't find file
+ {
+ dst_id = insertPath(ii->includeName,ii->local,FALSE);
+ }
+
+ DBG_CTX(("-----> FileDef includeInfo for %s\n", ii->includeName.data()));
+ DBG_CTX((" local: %d\n", ii->local));
+ DBG_CTX((" imported: %d\n", ii->imported));
+ DBG_CTX((" indirect: %d\n", ii->indirect));
+ if(ii->fileDef)
+ {
+ DBG_CTX(("include: %s\n", ii->fileDef->absFilePath().data()));
+ }
+ DBG_CTX((" src_id : %d\n", src_id));
+ DBG_CTX((" dst_id: %d\n", dst_id));
+
bindIntParameter(incl_select,":local",ii->local);
- bindIntParameter(incl_select,":id_src",id_src);
- bindIntParameter(incl_select,":id_dst",id_dst);
+ bindIntParameter(incl_select,":src_id",src_id);
+ bindIntParameter(incl_select,":dst_id",dst_id);
if (step(incl_select,TRUE,TRUE)==0) {
bindIntParameter(incl_insert,":local",ii->local);
- bindIntParameter(incl_insert,":id_src",id_src);
- bindIntParameter(incl_insert,":id_dst",id_dst);
+ bindIntParameter(incl_insert,":src_id",src_id);
+ bindIntParameter(incl_insert,":dst_id",dst_id);
step(incl_insert);
}
}
@@ -1390,15 +2255,37 @@ static void generateSqlite3ForFile(const FileDef *fd)
QListIterator<IncludeInfo> ili(*fd->includedByFileList());
for (ili.toFirst();(ii=ili.current());++ili)
{
- int id_src=insertFile(ii->includeName);
- int id_dst=insertFile(fd->absFilePath());
+ int dst_id=insertPath(fd->absFilePath(),!fd->isReference());
+ int src_id;
+ QCString src_path;
+
+ if(ii->fileDef) // found file
+ {
+ if(ii->fileDef->isReference())
+ {
+ // strip tagfile from path
+ QCString tagfile = ii->fileDef->getReference();
+ src_path = ii->fileDef->absFilePath().copy();
+ src_path.stripPrefix(tagfile+":");
+ }
+ else
+ {
+ src_path = ii->fileDef->absFilePath();
+ }
+ src_id = insertPath(src_path,ii->local);
+ }
+ else // can't find file
+ {
+ src_id = insertPath(ii->includeName,ii->local,FALSE);
+ }
+
bindIntParameter(incl_select,":local",ii->local);
- bindIntParameter(incl_select,":id_src",id_src);
- bindIntParameter(incl_select,":id_dst",id_dst);
+ bindIntParameter(incl_select,":src_id",src_id);
+ bindIntParameter(incl_select,":dst_id",dst_id);
if (step(incl_select,TRUE,TRUE)==0) {
bindIntParameter(incl_insert,":local",ii->local);
- bindIntParameter(incl_insert,":id_src",id_src);
- bindIntParameter(incl_insert,":id_dst",id_dst);
+ bindIntParameter(incl_insert,":src_id",src_id);
+ bindIntParameter(incl_insert,":dst_id",dst_id);
step(incl_insert);
}
}
@@ -1407,13 +2294,13 @@ static void generateSqlite3ForFile(const FileDef *fd)
// + contained class definitions
if (fd->getClassSDict())
{
- writeInnerClasses(fd->getClassSDict());
+ writeInnerClasses(fd->getClassSDict(),refid);
}
// + contained namespace definitions
if (fd->getNamespaceSDict())
{
- writeInnerNamespaces(fd->getNamespaceSDict());
+ writeInnerNamespaces(fd->getNamespaceSDict(),refid);
}
// + member groups
@@ -1423,7 +2310,7 @@ static void generateSqlite3ForFile(const FileDef *fd)
MemberGroup *mg;
for (;(mg=mgli.current());++mgli)
{
- generateSqlite3Section(fd,mg->members(),"user-defined",mg->header(),
+ generateSqlite3Section(fd,mg->members(),refid,"user-defined",mg->header(),
mg->documentation());
}
}
@@ -1435,24 +2322,201 @@ static void generateSqlite3ForFile(const FileDef *fd)
{
if ((ml->listType()&MemberListType_declarationLists)!=0)
{
- generateSqlite3Section(fd,ml,"user-defined");//g_xmlSectionMapper.find(ml->listType()));
+ generateSqlite3Section(fd,ml,refid,"user-defined");
}
}
}
+// kind: group
static void generateSqlite3ForGroup(const GroupDef *gd)
{
-#warning WorkInProgress
+ // + members
+ // + member groups
+ // + files
+ // + classes
+ // + namespaces
+ // - packages
+ // + pages
+ // + child groups
+ // - examples
+ // + brief description
+ // + detailed description
+
+ if (gd->isReference()) return; // skip external references.
+
+ struct Refid refid = insertRefid(gd->getOutputFileBase());
+ if(!refid.created && compounddefExists(refid)){return;}
+ bindIntParameter(compounddef_insert,":rowid", refid.rowid);
+
+ bindTextParameter(compounddef_insert,":name",gd->name());
+ bindTextParameter(compounddef_insert,":title",gd->groupTitle(), FALSE);
+ bindTextParameter(compounddef_insert,":kind","group",FALSE);
+
+ int file_id = insertPath(gd->getDefFileName());
+ bindIntParameter(compounddef_insert,":file_id",file_id);
+ bindIntParameter(compounddef_insert,":line",gd->getDefLine());
+ bindIntParameter(compounddef_insert,":column",gd->getDefColumn());
+
+ getSQLDesc(compounddef_insert,":briefdescription",gd->briefDescription(),gd);
+ getSQLDesc(compounddef_insert,":detaileddescription",gd->documentation(),gd);
+
+ step(compounddef_insert);
+
+ // + files
+ writeInnerFiles(gd->getFiles(),refid);
+
+ // + classes
+ writeInnerClasses(gd->getClasses(),refid);
+
+ // + namespaces
+ writeInnerNamespaces(gd->getNamespaces(),refid);
+
+ // + pages
+ writeInnerPages(gd->getPages(),refid);
+
+ // + groups
+ writeInnerGroups(gd->getSubGroups(),refid);
+
+ // + member groups
+ if (gd->getMemberGroupSDict())
+ {
+ MemberGroupSDict::Iterator mgli(*gd->getMemberGroupSDict());
+ MemberGroup *mg;
+ for (;(mg=mgli.current());++mgli)
+ {
+ generateSqlite3Section(gd,mg->members(),refid,"user-defined",mg->header(),
+ mg->documentation());
+ }
+ }
+
+ // + members
+ QListIterator<MemberList> mli(gd->getMemberLists());
+ MemberList *ml;
+ for (mli.toFirst();(ml=mli.current());++mli)
+ {
+ if ((ml->listType()&MemberListType_declarationLists)!=0)
+ {
+ generateSqlite3Section(gd,ml,refid,"user-defined");
+ }
+ }
}
+// kind: dir
static void generateSqlite3ForDir(const DirDef *dd)
{
-#warning WorkInProgress
+ // + dirs
+ // + files
+ // + briefdescription
+ // + detaileddescription
+ // + location (below uses file_id, line, column; XML just uses file)
+ if (dd->isReference()) return; // skip external references
+
+ struct Refid refid = insertRefid(dd->getOutputFileBase());
+ if(!refid.created && compounddefExists(refid)){return;}
+ bindIntParameter(compounddef_insert,":rowid", refid.rowid);
+
+ bindTextParameter(compounddef_insert,":name",dd->displayName());
+ bindTextParameter(compounddef_insert,":kind","dir",FALSE);
+
+ int file_id = insertPath(dd->getDefFileName(),TRUE,TRUE,2);
+ bindIntParameter(compounddef_insert,":file_id",file_id);
+
+ /*
+ line and column are weird here, but:
+ - dir goes into compounddef with all of the others
+ - the semantics would be fine if we set them to NULL here
+ - but defining line and column as NOT NULL is an important promise
+ for other compounds, so I don't want to loosen it
+
+ For reference, the queries return 1.
+ 0 or -1 make more sense, but I see that as a change for DirDef.
+ */
+ bindIntParameter(compounddef_insert,":line",dd->getDefLine());
+ bindIntParameter(compounddef_insert,":column",dd->getDefColumn());
+
+ getSQLDesc(compounddef_insert,":briefdescription",dd->briefDescription(),dd);
+ getSQLDesc(compounddef_insert,":detaileddescription",dd->documentation(),dd);
+
+ step(compounddef_insert);
+
+ // + files
+ writeInnerDirs(&dd->subDirs(),refid);
+
+ // + files
+ writeInnerFiles(dd->getFiles(),refid);
}
+// kinds: page, example
static void generateSqlite3ForPage(const PageDef *pd,bool isExample)
{
-#warning WorkInProgress
+ // + name
+ // + title
+ // + brief description
+ // + documentation (detailed description)
+ // + inbody documentation
+ // + sub pages
+ if (pd->isReference()) return; // skip external references.
+
+ // TODO: do we more special handling if isExample?
+
+ QCString qrefid = pd->getOutputFileBase();
+ if (pd->getGroupDef())
+ {
+ qrefid+=(QCString)"_"+pd->name();
+ }
+ if (qrefid=="index") qrefid="indexpage"; // to prevent overwriting the generated index page.
+
+ struct Refid refid = insertRefid(qrefid);
+
+ // can omit a page that already has a refid
+ if(!refid.created && compounddefExists(refid)){return;}
+
+ bindIntParameter(compounddef_insert,":rowid",refid.rowid);
+ // + name
+ bindTextParameter(compounddef_insert,":name",pd->name());
+
+ QCString title;
+ if (pd==Doxygen::mainPage) // main page is special
+ {
+ if (!pd->title().isEmpty() && pd->title().lower()!="notitle")
+ {
+ title = filterTitle(convertCharEntitiesToUTF8(Doxygen::mainPage->title()));
+ }
+ else
+ {
+ title = Config_getString(PROJECT_NAME);
+ }
+ }
+ else
+ {
+ SectionInfo *si = Doxygen::sectionDict->find(pd->name());
+ if (si)
+ {
+ title = si->title;
+ }
+
+ if(!title){title = pd->title();}
+ }
+
+ // + title
+ bindTextParameter(compounddef_insert,":title",title,FALSE);
+
+ bindTextParameter(compounddef_insert,":kind", isExample ? "example" : "page");
+
+ int file_id = insertPath(pd->getDefFileName());
+
+ bindIntParameter(compounddef_insert,":file_id",file_id);
+ bindIntParameter(compounddef_insert,":line",pd->getDefLine());
+ bindIntParameter(compounddef_insert,":column",pd->getDefColumn());
+
+ // + brief description
+ getSQLDesc(compounddef_insert,":briefdescription",pd->briefDescription(),pd);
+ // + documentation (detailed description)
+ getSQLDesc(compounddef_insert,":detaileddescription",pd->documentation(),pd);
+
+ step(compounddef_insert);
+ // + sub pages
+ writeInnerPages(pd->getSubPages(),refid);
}
@@ -1463,6 +2527,7 @@ static sqlite3* openDbConnection()
QDir sqlite3Dir(outputDirectory);
sqlite3 *db;
int rc;
+ struct stat buf;
rc = sqlite3_initialize();
if (rc != SQLITE_OK)
@@ -1470,7 +2535,21 @@ static sqlite3* openDbConnection()
msg("sqlite3_initialize failed\n");
return NULL;
}
- rc = sqlite3_open_v2(outputDirectory+"/doxygen_sqlite3.db", &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
+
+
+ if (stat (outputDirectory+"/doxygen_sqlite3.db", &buf) == 0)
+ {
+ msg("doxygen_sqlite3.db already exists! aborting sqlite3 output generation!\n");
+ msg("If you wish to re-generate the database, remove or archive the existing copy first.\n");
+ return NULL;
+ }
+
+ rc = sqlite3_open_v2(
+ outputDirectory+"/doxygen_sqlite3.db",
+ &db,
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
+ 0
+ );
if (rc != SQLITE_OK)
{
sqlite3_close(db);
@@ -1497,10 +2576,16 @@ void generateSqlite3()
{
return;
}
+
+# ifdef SQLITE3_DEBUG
+ // debug: show all executed statements
+ sqlite3_trace(db, &sqlLog, NULL);
+# endif
+
beginTransaction(db);
pragmaTuning(db);
- if (-1==initializeSchema(db))
+ if (-1==initializeTables(db))
return;
if ( -1 == prepareStatements(db) )
@@ -1509,9 +2594,11 @@ void generateSqlite3()
return;
}
+ recordMetadata();
+
// + classes
ClassSDict::Iterator cli(*Doxygen::classSDict);
- ClassDef *cd;
+ const ClassDef *cd;
for (cli.toFirst();(cd=cli.current());++cli)
{
msg("Generating Sqlite3 output for class %s\n",cd->name().data());
@@ -1520,7 +2607,7 @@ void generateSqlite3()
// + namespaces
NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
- NamespaceDef *nd;
+ const NamespaceDef *nd;
for (nli.toFirst();(nd=nli.current());++nli)
{
msg("Generating Sqlite3 output for namespace %s\n",nd->name().data());
@@ -1533,7 +2620,7 @@ void generateSqlite3()
for (;(fn=fnli.current());++fnli)
{
FileNameIterator fni(*fn);
- FileDef *fd;
+ const FileDef *fd;
for (;(fd=fni.current());++fni)
{
msg("Generating Sqlite3 output for file %s\n",fd->name().data());
@@ -1543,7 +2630,7 @@ void generateSqlite3()
// + groups
GroupSDict::Iterator gli(*Doxygen::groupSDict);
- GroupDef *gd;
+ const GroupDef *gd;
for (;(gd=gli.current());++gli)
{
msg("Generating Sqlite3 output for group %s\n",gd->name().data());
@@ -1553,7 +2640,7 @@ void generateSqlite3()
// + page
{
PageSDict::Iterator pdi(*Doxygen::pageSDict);
- PageDef *pd=0;
+ const PageDef *pd=0;
for (pdi.toFirst();(pd=pdi.current());++pdi)
{
msg("Generating Sqlite3 output for page %s\n",pd->name().data());
@@ -1563,7 +2650,7 @@ void generateSqlite3()
// + dirs
{
- DirDef *dir;
+ const DirDef *dir;
DirSDict::Iterator sdi(*Doxygen::directories);
for (sdi.toFirst();(dir=sdi.current());++sdi)
{
@@ -1575,7 +2662,7 @@ void generateSqlite3()
// + examples
{
PageSDict::Iterator pdi(*Doxygen::exampleSDict);
- PageDef *pd=0;
+ const PageDef *pd=0;
for (pdi.toFirst();(pd=pdi.current());++pdi)
{
msg("Generating Sqlite3 output for example %s\n",pd->name().data());
@@ -1590,6 +2677,11 @@ void generateSqlite3()
generateSqlite3ForPage(Doxygen::mainPage,FALSE);
}
+ // TODO: copied from initializeSchema; not certain if we should say/do more
+ // if there's a failure here?
+ if (-1==initializeViews(db))
+ return;
+
endTransaction(db);
}
diff --git a/src/tagreader.cpp b/src/tagreader.cpp
index 942c55b..1afa30d 100644
--- a/src/tagreader.cpp
+++ b/src/tagreader.cpp
@@ -102,6 +102,7 @@ class TagClassInfo
QCString name;
QCString filename;
QCString clangId;
+ QCString anchor;
TagAnchorInfoList docAnchors;
QList<BaseInfo> *bases;
QList<TagMemberInfo> members;
@@ -382,7 +383,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Unknown compound attribute `%s' found!\n",kind.data());
+ warn("Unknown compound attribute `%s' found!",kind.data());
m_state = Invalid;
}
if (isObjC=="yes" && m_curClass)
@@ -410,7 +411,7 @@ class TagFileParser : public QXmlDefaultHandler
case InPackage: m_tagFilePackages.append(m_curPackage);
m_curPackage=0; break;
default:
- warn("tag `compound' was not expected!\n");
+ warn("tag `compound' was not expected!");
}
}
@@ -456,7 +457,7 @@ class TagFileParser : public QXmlDefaultHandler
case InNamespace: m_curNamespace->members.append(m_curMember); break;
case InGroup: m_curGroup->members.append(m_curMember); break;
case InPackage: m_curPackage->members.append(m_curMember); break;
- default: warn("Unexpected tag `member' found\n"); break;
+ default: warn("Unexpected tag `member' found"); break;
}
}
@@ -474,7 +475,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Found enumvalue tag outside of member tag\n");
+ warn("Found `enumvalue' tag outside of member tag");
}
}
@@ -502,7 +503,7 @@ class TagFileParser : public QXmlDefaultHandler
case InMember: m_curMember->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
case InPackage: m_curPackage->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
case InDir: m_curDir->docAnchors.append(new TagAnchorInfo(m_fileName,m_curString,m_title)); break;
- default: warn("Unexpected tag `member' found\n"); break;
+ default: warn("Unexpected tag `docanchor' found"); break;
}
}
@@ -515,7 +516,7 @@ class TagFileParser : public QXmlDefaultHandler
case InNamespace: m_curNamespace->classList.append(m_curString); break;
case InGroup: m_curGroup->classList.append(m_curString); break;
case InPackage: m_curPackage->classList.append(m_curString); break;
- default: warn("Unexpected tag `class' found\n"); break;
+ default: warn("Unexpected tag `class' found"); break;
}
}
@@ -526,7 +527,7 @@ class TagFileParser : public QXmlDefaultHandler
case InNamespace: m_curNamespace->classList.append(m_curString); break;
case InFile: m_curFile->namespaceList.append(m_curString); break;
case InGroup: m_curGroup->namespaceList.append(m_curString); break;
- default: warn("Unexpected tag `namespace' found\n"); break;
+ default: warn("Unexpected tag `namespace' found"); break;
}
}
@@ -536,7 +537,7 @@ class TagFileParser : public QXmlDefaultHandler
{
case InGroup: m_curGroup->fileList.append(m_curString); break;
case InDir: m_curDir->fileList.append(m_curString); break;
- default: warn("Unexpected tag `file' found\n"); break;
+ default: warn("Unexpected tag `file' found"); break;
}
}
@@ -545,7 +546,7 @@ class TagFileParser : public QXmlDefaultHandler
switch(m_state)
{
case InGroup: m_curGroup->fileList.append(m_curString); break;
- default: warn("Unexpected tag `page' found\n"); break;
+ default: warn("Unexpected tag `page' found"); break;
}
}
@@ -554,7 +555,7 @@ class TagFileParser : public QXmlDefaultHandler
switch(m_state)
{
case InDir: m_curDir->subdirList.append(m_curString); break;
- default: warn("Unexpected tag `page' found\n"); break;
+ default: warn("Unexpected tag `dir' found"); break;
}
}
@@ -578,7 +579,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Unexpected tag `type' found\n");
+ warn("Unexpected tag `type' found");
}
}
@@ -594,7 +595,7 @@ class TagFileParser : public QXmlDefaultHandler
case InDir: m_curDir->name = m_curString; break;
case InMember: m_curMember->name = m_curString; break;
case InPackage: m_curPackage->name = m_curString; break;
- default: warn("Unexpected tag `name' found\n"); break;
+ default: warn("Unexpected tag `name' found"); break;
}
}
@@ -628,7 +629,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Unexpected tag `base' found\n");
+ warn("Unexpected tag `base' found");
}
}
@@ -640,7 +641,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Unexpected tag `base' found\n");
+ warn("Unexpected tag `base' found");
}
}
@@ -657,7 +658,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Unexpected tag `includes' found\n");
+ warn("Unexpected tag `includes' found");
}
m_curString="";
}
@@ -680,7 +681,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Unexpected tag `templarg' found\n");
+ warn("Unexpected tag `templarg' found");
}
}
@@ -695,7 +696,7 @@ class TagFileParser : public QXmlDefaultHandler
case InPage: m_curPage->filename = m_curString; break;
case InPackage: m_curPackage->filename = m_curString; break;
case InDir: m_curDir->filename = m_curString; break;
- default: warn("Unexpected tag `filename' found\n"); break;
+ default: warn("Unexpected tag `filename' found"); break;
}
}
@@ -705,7 +706,7 @@ class TagFileParser : public QXmlDefaultHandler
{
case InFile: m_curFile->path = m_curString; break;
case InDir: m_curDir->path = m_curString; break;
- default: warn("Unexpected tag `path' found\n"); break;
+ default: warn("Unexpected tag `path' found"); break;
}
}
@@ -715,9 +716,13 @@ class TagFileParser : public QXmlDefaultHandler
{
m_curMember->anchor = m_curString;
}
+ else if (m_state==InClass)
+ {
+ m_curClass->anchor = m_curString;
+ }
else
{
- warn("Unexpected tag `anchor' found\n");
+ warn("Unexpected tag `anchor' found");
}
}
@@ -737,7 +742,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("warning: Unexpected tag `anchor' found\n");
+ warn("Unexpected tag `clangid' found");
}
}
@@ -751,7 +756,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Unexpected tag `anchorfile' found\n");
+ warn("Unexpected tag `anchorfile' found");
}
}
@@ -763,7 +768,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Unexpected tag `arglist' found\n");
+ warn("Unexpected tag `arglist' found");
}
}
void endTitle()
@@ -772,7 +777,7 @@ class TagFileParser : public QXmlDefaultHandler
{
case InGroup: m_curGroup->title = m_curString; break;
case InPage: m_curPage->title = m_curString; break;
- default: warn("Unexpected tag `title' found\n"); break;
+ default: warn("Unexpected tag `title' found"); break;
}
}
@@ -784,7 +789,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Unexpected tag `subgroup' found\n");
+ warn("Unexpected tag `subgroup' found");
}
}
@@ -879,7 +884,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Unknown tag `%s' found!\n",name.data());
+ warn("Unknown tag `%s' found!",name.data());
}
return TRUE;
}
@@ -894,7 +899,7 @@ class TagFileParser : public QXmlDefaultHandler
}
else
{
- warn("Unknown tag `%s' found!\n",name.data());
+ warn("Unknown tag `%s' found!",name.data());
}
return TRUE;
}
@@ -1158,7 +1163,7 @@ void TagFileParser::addDocAnchors(Entry *e,const TagAnchorInfoList &l)
}
else
{
- warn("Duplicate anchor %s found\n",ta->label.data());
+ warn("Duplicate anchor %s found",ta->label.data());
}
}
}
@@ -1335,6 +1340,7 @@ void TagFileParser::buildLists(Entry *root)
addDocAnchors(ce,tci->docAnchors);
TagInfo *ti = new TagInfo;
ti->tagName = m_tagName;
+ ti->anchor = tci->anchor;
ti->fileName = tci->filename;
ce->id = tci->clangId;
ce->tagInfo = ti;
diff --git a/src/template.cpp b/src/template.cpp
index 3e39d3c..b1435ce 100644
--- a/src/template.cpp
+++ b/src/template.cpp
@@ -698,7 +698,7 @@ class FilterTexLabel
{
if (v.isValid() && (v.type()==TemplateVariant::String))
{
- return TemplateVariant(latexEscapeLabelName(v.toString(),FALSE),TRUE);
+ return TemplateVariant(latexEscapeLabelName(v.toString()),TRUE);
}
else
{
@@ -717,7 +717,7 @@ class FilterTexIndex
{
if (v.isValid() && (v.type()==TemplateVariant::String))
{
- return TemplateVariant(latexEscapeIndexChars(v.toString(),FALSE),TRUE);
+ return TemplateVariant(latexEscapeIndexChars(v.toString()),TRUE);
}
else
{
diff --git a/src/util.cpp b/src/util.cpp
index afb9905..5d72a9d 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -6638,6 +6638,8 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle,
// append documentation block to the page.
pd->setDocumentation(doc,fileName,startLine);
//printf("Adding page docs `%s' pi=%p name=%s\n",doc.data(),pd,name);
+ // append (x)refitems to the page.
+ pd->setRefItems(sli);
}
else // new page
{
@@ -6927,7 +6929,7 @@ void filterLatexString(FTextStream &t,const char *str,
}
}
-QCString latexEscapeLabelName(const char *s,bool insideTabbing)
+QCString latexEscapeLabelName(const char *s)
{
QGString result;
QCString tmp(qstrlen(s)+1);
@@ -6957,14 +6959,14 @@ QCString latexEscapeLabelName(const char *s,bool insideTabbing)
p++;
}
tmp[i]=0;
- filterLatexString(t,tmp.data(),insideTabbing);
+ filterLatexString(t,tmp,TRUE);
break;
}
}
return result.data();
}
-QCString latexEscapeIndexChars(const char *s,bool insideTabbing)
+QCString latexEscapeIndexChars(const char *s)
{
QGString result;
QCString tmp(qstrlen(s)+1);
@@ -6995,7 +6997,7 @@ QCString latexEscapeIndexChars(const char *s,bool insideTabbing)
p++;
}
tmp[i]=0;
- filterLatexString(t,tmp.data(),insideTabbing);
+ filterLatexString(t,tmp.data(),TRUE);
break;
}
}
@@ -7026,6 +7028,25 @@ QCString latexEscapePDFString(const char *s)
return result.data();
}
+QCString latexFilterURL(const char *s)
+{
+ QGString result;
+ FTextStream t(&result);
+ const char *p=s;
+ char c;
+ while ((c=*p++))
+ {
+ switch (c)
+ {
+ case '#': t << "\\#"; break;
+ default:
+ t << c;
+ break;
+ }
+ }
+ return result.data();
+}
+
QCString rtfFormatBmkStr(const char *name)
{
diff --git a/src/util.h b/src/util.h
index 2ee8b17..4274f65 100644
--- a/src/util.h
+++ b/src/util.h
@@ -345,9 +345,10 @@ void filterLatexString(FTextStream &t,const char *str,
bool insideItem=FALSE,
bool keepSpaces=FALSE);
-QCString latexEscapeLabelName(const char *s,bool insideTabbing);
-QCString latexEscapeIndexChars(const char *s,bool insideTabbing);
+QCString latexEscapeLabelName(const char *s);
+QCString latexEscapeIndexChars(const char *s);
QCString latexEscapePDFString(const char *s);
+QCString latexFilterURL(const char *s);
QCString rtfFormatBmkStr(const char *name);
diff --git a/src/vhdlcode.l b/src/vhdlcode.l
index 68dcafb..ee0731f 100644
--- a/src/vhdlcode.l
+++ b/src/vhdlcode.l
@@ -370,7 +370,7 @@ static void codifyLines(const char *text,const char *cl=0,bool classlink=FALSE,b
//g_code->codify(sp);
if (comment)
{
- writeFont("keyword",line.data());
+ writeFont("comment",line.data());
}
else
{
@@ -381,7 +381,7 @@ static void codifyLines(const char *text,const char *cl=0,bool classlink=FALSE,b
else
{
if (comment)
- writeFont("keyword",sp);
+ writeFont("comment",sp);
else
writeWord(sp,cl,classlink);
done=TRUE;
@@ -1478,11 +1478,11 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI
writeFont("keyword",vhdlcodeYYtext);
}
-<Bases>^{B}*{XILINX}[^\n]* {
- writeWord(yytext);
- //codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
- }
-
+<Bases>^{B}*{XILINX}/[^a-zA-Z0-9_] {
+ writeWord(yytext);
+ //codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
+ }
+
<Bases>^{B}*"set_"[^\n]* {
writeWord(yytext);
}
@@ -1497,37 +1497,38 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI
}
<*>\n{TEXTT} { // found normal or special comment on its own line
- QCString text(vhdlcodeYYtext);
- int i=text.find("--");
- if (text.mid(i,3)=="--!" && // hide special comment
- Config_getBool(STRIP_CODE_COMMENTS))
- {
- g_yyLineNr++; // skip complete line
- }
- else // normal comment
- {
- // startFontClass("keyword");
- codifyLines(text,0,FALSE,TRUE);
- // endFontClass();
- }
+ QCString text(vhdlcodeYYtext);
+ int i=text.find("--");
+ if (text.mid(i,3)=="--!") // && // hide special comment
+ {
+ if (!Config_getBool(STRIP_CODE_COMMENTS))
+ {
+ codifyLines(text,0,FALSE,TRUE);
+ }
+ g_yyLineNr++; // skip complete line
+ }
+ else // normal comment
+ {
+ codifyLines(text,0,FALSE,TRUE);
+ }
}
<*>{TEXTT} { // found normal or special comment after something
- QCString text(vhdlcodeYYtext);
- int i=text.find("--");
- if (text.mid(i,3)=="--!" &&
- Config_getBool(STRIP_CODE_COMMENTS))
- {
- // hide special comment
- }
- else // normal comment
- {
- // startFontClass("keyword");
- codifyLines(text,0,FALSE,TRUE);
- // endFontClass();
- }
+ QCString text(vhdlcodeYYtext);
+ int i=text.find("--");
+ if (text.mid(i,3)=="--!")
+ {
+ // hide special comment
+ if (!Config_getBool(STRIP_CODE_COMMENTS))
+ {
+ codifyLines(text,0,FALSE,TRUE);
+ }
+ }
+ else // normal comment
+ {
+ codifyLines(text,0,FALSE,TRUE);
+ }
}
-
%%
/*@ ----------------------------------------------------------------------------
diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp
index 9ac0cfd..f603ddd 100644
--- a/src/vhdldocgen.cpp
+++ b/src/vhdldocgen.cpp
@@ -602,7 +602,7 @@ const char* g_vhdlKeyWordMap1[] =
{
"natural","unsigned","signed","string","boolean", "bit","bit_vector","character",
"std_ulogic","std_ulogic_vector","std_logic","std_logic_vector","integer",
- "real","float","ufixed","sfixed","time",0
+ "real","float","ufixed","sfixed","time","positive",0
};
// logic
@@ -667,7 +667,7 @@ const char* g_vhdlKeyWordMap3[] =
QCString* VhdlDocGen::findKeyWord(const QCString& tmp)
{
static QCString vhdlkeyword("vhdlkeyword");
- static QCString vhdltype("comment");
+ static QCString vhdltype("keywordtype");
static QCString vhdllogic("vhdllogic");
static QCString preprocessor("keywordflow");
diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp
index 525dbf5..35e9194 100644
--- a/src/xmldocvisitor.cpp
+++ b/src/xmldocvisitor.cpp
@@ -494,7 +494,7 @@ void XmlDocVisitor::visitPre(DocPara *)
void XmlDocVisitor::visitPost(DocPara *)
{
if (m_hide) return;
- m_t << "</para>";
+ m_t << "</para>" << endl;
}
void XmlDocVisitor::visitPre(DocRoot *)
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index be866a2..e003319 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -222,146 +222,117 @@ class TextGeneratorXMLImpl : public TextGeneratorIntf
/** Generator for producing XML formatted source code. */
-class XMLCodeGenerator : public CodeOutputInterface
+void XMLCodeGenerator::codify(const char *text)
{
- public:
-
- XMLCodeGenerator(FTextStream &t) : m_t(t), m_lineNumber(-1), m_isMemberRef(FALSE), m_col(0),
- m_insideCodeLine(FALSE), m_normalHLNeedStartTag(TRUE), m_insideSpecialHL(FALSE) {}
- virtual ~XMLCodeGenerator() { }
-
- void codify(const char *text)
- {
- XML_DB(("(codify \"%s\")\n",text));
- if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
- {
- m_t << "<highlight class=\"normal\">";
- m_normalHLNeedStartTag=FALSE;
- }
- writeXMLCodeString(m_t,text,m_col);
- }
- void writeCodeLink(const char *ref,const char *file,
- const char *anchor,const char *name,
- const char *tooltip)
- {
- XML_DB(("(writeCodeLink)\n"));
- if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
- {
- m_t << "<highlight class=\"normal\">";
- m_normalHLNeedStartTag=FALSE;
- }
- writeXMLLink(m_t,ref,file,anchor,name,tooltip);
- m_col+=qstrlen(name);
- }
- void writeTooltip(const char *, const DocLinkInfo &, const char *,
- const char *, const SourceLinkInfo &, const SourceLinkInfo &
- )
- {
- XML_DB(("(writeToolTip)\n"));
- }
- void startCodeLine(bool)
- {
- XML_DB(("(startCodeLine)\n"));
- m_t << "<codeline";
- if (m_lineNumber!=-1)
- {
- m_t << " lineno=\"" << m_lineNumber << "\"";
- if (!m_refId.isEmpty())
- {
- m_t << " refid=\"" << m_refId << "\"";
- if (m_isMemberRef)
- {
- m_t << " refkind=\"member\"";
- }
- else
- {
- m_t << " refkind=\"compound\"";
- }
- }
- if (!m_external.isEmpty())
- {
- m_t << " external=\"" << m_external << "\"";
- }
- }
- m_t << ">";
- m_insideCodeLine=TRUE;
- m_col=0;
- }
- void endCodeLine()
- {
- XML_DB(("(endCodeLine)\n"));
- if (!m_insideSpecialHL && !m_normalHLNeedStartTag)
- {
- m_t << "</highlight>";
- m_normalHLNeedStartTag=TRUE;
- }
- m_t << "</codeline>" << endl; // non DocBook
- m_lineNumber = -1;
- m_refId.resize(0);
- m_external.resize(0);
- m_insideCodeLine=FALSE;
- }
- void startFontClass(const char *colorClass)
+ XML_DB(("(codify \"%s\")\n",text));
+ if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
+ {
+ m_t << "<highlight class=\"normal\">";
+ m_normalHLNeedStartTag=FALSE;
+ }
+ writeXMLCodeString(m_t,text,m_col);
+}
+void XMLCodeGenerator::writeCodeLink(const char *ref,const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip)
+{
+ XML_DB(("(writeCodeLink)\n"));
+ if (m_insideCodeLine && !m_insideSpecialHL && m_normalHLNeedStartTag)
+ {
+ m_t << "<highlight class=\"normal\">";
+ m_normalHLNeedStartTag=FALSE;
+ }
+ writeXMLLink(m_t,ref,file,anchor,name,tooltip);
+ m_col+=qstrlen(name);
+}
+void XMLCodeGenerator::writeTooltip(const char *, const DocLinkInfo &, const char *,
+ const char *, const SourceLinkInfo &, const SourceLinkInfo &
+ )
+{
+ XML_DB(("(writeToolTip)\n"));
+}
+void XMLCodeGenerator::startCodeLine(bool)
+{
+ XML_DB(("(startCodeLine)\n"));
+ m_t << "<codeline";
+ if (m_lineNumber!=-1)
+ {
+ m_t << " lineno=\"" << m_lineNumber << "\"";
+ if (!m_refId.isEmpty())
{
- XML_DB(("(startFontClass)\n"));
- if (m_insideCodeLine && !m_insideSpecialHL && !m_normalHLNeedStartTag)
+ m_t << " refid=\"" << m_refId << "\"";
+ if (m_isMemberRef)
{
- m_t << "</highlight>";
- m_normalHLNeedStartTag=TRUE;
+ m_t << " refkind=\"member\"";
}
- m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook
- m_insideSpecialHL=TRUE;
- }
- void endFontClass()
- {
- XML_DB(("(endFontClass)\n"));
- m_t << "</highlight>"; // non DocBook
- m_insideSpecialHL=FALSE;
- }
- void writeCodeAnchor(const char *)
- {
- XML_DB(("(writeCodeAnchor)\n"));
- }
- void writeLineNumber(const char *extRef,const char *compId,
- const char *anchorId,int l)
- {
- XML_DB(("(writeLineNumber)\n"));
- // we remember the information provided here to use it
- // at the <codeline> start tag.
- m_lineNumber = l;
- if (compId)
+ else
{
- m_refId=compId;
- if (anchorId) m_refId+=(QCString)"_1"+anchorId;
- m_isMemberRef = anchorId!=0;
- if (extRef) m_external=extRef;
+ m_t << " refkind=\"compound\"";
}
}
- void setCurrentDoc(Definition *,const char *,bool)
- {
- }
- void addWord(const char *,bool)
+ if (!m_external.isEmpty())
{
+ m_t << " external=\"" << m_external << "\"";
}
-
- void finish()
- {
- if (m_insideCodeLine) endCodeLine();
- }
-
- private:
- FTextStream &m_t;
- QCString m_refId;
- QCString m_external;
- int m_lineNumber;
- bool m_isMemberRef;
- int m_col;
-
- bool m_insideCodeLine;
- bool m_normalHLNeedStartTag;
- bool m_insideSpecialHL;
-};
-
+ }
+ m_t << ">";
+ m_insideCodeLine=TRUE;
+ m_col=0;
+}
+void XMLCodeGenerator::endCodeLine()
+{
+ XML_DB(("(endCodeLine)\n"));
+ if (!m_insideSpecialHL && !m_normalHLNeedStartTag)
+ {
+ m_t << "</highlight>";
+ m_normalHLNeedStartTag=TRUE;
+ }
+ m_t << "</codeline>" << endl; // non DocBook
+ m_lineNumber = -1;
+ m_refId.resize(0);
+ m_external.resize(0);
+ m_insideCodeLine=FALSE;
+}
+void XMLCodeGenerator::startFontClass(const char *colorClass)
+{
+ XML_DB(("(startFontClass)\n"));
+ if (m_insideCodeLine && !m_insideSpecialHL && !m_normalHLNeedStartTag)
+ {
+ m_t << "</highlight>";
+ m_normalHLNeedStartTag=TRUE;
+ }
+ m_t << "<highlight class=\"" << colorClass << "\">"; // non DocBook
+ m_insideSpecialHL=TRUE;
+}
+void XMLCodeGenerator::endFontClass()
+{
+ XML_DB(("(endFontClass)\n"));
+ m_t << "</highlight>"; // non DocBook
+ m_insideSpecialHL=FALSE;
+}
+void XMLCodeGenerator::writeCodeAnchor(const char *)
+{
+ XML_DB(("(writeCodeAnchor)\n"));
+}
+void XMLCodeGenerator::writeLineNumber(const char *extRef,const char *compId,
+ const char *anchorId,int l)
+{
+ XML_DB(("(writeLineNumber)\n"));
+ // we remember the information provided here to use it
+ // at the <codeline> start tag.
+ m_lineNumber = l;
+ if (compId)
+ {
+ m_refId=compId;
+ if (anchorId) m_refId+=(QCString)"_1"+anchorId;
+ m_isMemberRef = anchorId!=0;
+ if (extRef) m_external=extRef;
+ }
+}
+void XMLCodeGenerator::finish()
+{
+ if (m_insideCodeLine) endCodeLine();
+}
static void writeTemplateArgumentList(ArgumentList *al,
FTextStream &t,
@@ -1163,7 +1134,7 @@ static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t)
NamespaceDef *nd;
for (nli.toFirst();(nd=nli.current());++nli)
{
- if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymouse scopes
+ if (!nd->isHidden() && nd->name().find('@')==-1) // skip anonymous scopes
{
t << " <innernamespace refid=\"" << nd->getOutputFileBase()
<< "\">" << convertToXML(nd->name()) << "</innernamespace>" << endl;
diff --git a/src/xmlgen.h b/src/xmlgen.h
index 0447591..0555546 100644
--- a/src/xmlgen.h
+++ b/src/xmlgen.h
@@ -15,6 +15,48 @@
#ifndef XMLGEN_H
#define XMLGEN_H
+#include "outputgen.h"
+
+class XMLCodeGenerator : public CodeOutputInterface
+{
+ public:
+
+ XMLCodeGenerator(FTextStream &t) : m_t(t), m_lineNumber(-1), m_isMemberRef(FALSE), m_col(0),
+ m_insideCodeLine(FALSE), m_normalHLNeedStartTag(TRUE), m_insideSpecialHL(FALSE) {}
+ virtual ~XMLCodeGenerator() { }
+
+ void codify(const char *text);
+ void writeCodeLink(const char *ref,const char *file,
+ const char *anchor,const char *name,
+ const char *tooltip);
+ void writeTooltip(const char *, const DocLinkInfo &, const char *,
+ const char *, const SourceLinkInfo &, const SourceLinkInfo &
+ );
+ void startCodeLine(bool);
+ void endCodeLine();
+ void startFontClass(const char *colorClass);
+ void endFontClass();
+ void writeCodeAnchor(const char *);
+ void writeLineNumber(const char *extRef,const char *compId,
+ const char *anchorId,int l);
+ void setCurrentDoc(Definition *,const char *,bool){}
+ void addWord(const char *,bool){}
+
+ void finish();
+
+ private:
+ FTextStream &m_t;
+ QCString m_refId;
+ QCString m_external;
+ int m_lineNumber;
+ bool m_isMemberRef;
+ int m_col;
+
+ bool m_insideCodeLine;
+ bool m_normalHLNeedStartTag;
+ bool m_insideSpecialHL;
+};
+
void generateXML();
#endif
diff --git a/testing/009/bug.xml b/testing/009/bug.xml
index a6dfe88..34a411b 100644
--- a/testing/009/bug.xml
+++ b/testing/009/bug.xml
@@ -9,17 +9,16 @@
<para>
<variablelist>
<varlistentry>
- <term><anchor id="bug_1_bug000001"/>Class <ref refid="class_bug" kindref="compound">Bug</ref></term>
+ <term>Class <ref refid="class_bug" kindref="compound">Bug</ref></term>
</varlistentry>
<listitem>
- <para>Class bug. </para>
+ <para><anchor id="bug_1_bug000001"/>Class bug. </para>
</listitem>
<varlistentry>
- <term><anchor id="bug_1_bug000002"/>Member <ref refid="class_bug_1a1f720954dd97cd1203e80501a6eae74c" kindref="member">Bug::foo</ref> ()</term>
+ <term>Member <ref refid="class_bug_1a1f720954dd97cd1203e80501a6eae74c" kindref="member">Bug::foo</ref> ()</term>
</varlistentry>
<listitem>
- <para>Function bug<itemizedlist><listitem><para>list item 1 in bug</para></listitem><listitem><para>list item 2 in bug</para></listitem></itemizedlist>
-</para>
+ <para><anchor id="bug_1_bug000002"/>Function bug<itemizedlist><listitem><para>list item 1 in bug</para></listitem><listitem><para>list item 2 in bug</para></listitem></itemizedlist></para>
</listitem>
</variablelist>
</para>
diff --git a/testing/009/deprecated.xml b/testing/009/deprecated.xml
index 5db2acd..a787015 100644
--- a/testing/009/deprecated.xml
+++ b/testing/009/deprecated.xml
@@ -9,16 +9,16 @@
<para>
<variablelist>
<varlistentry>
- <term><anchor id="deprecated_1_deprecated000001"/>Class <ref refid="class_deprecated" kindref="compound">Deprecated</ref></term>
+ <term>Class <ref refid="class_deprecated" kindref="compound">Deprecated</ref></term>
</varlistentry>
<listitem>
- <para>This class is deprecated </para>
+ <para><anchor id="deprecated_1_deprecated000001"/>This class is deprecated </para>
</listitem>
<varlistentry>
- <term><anchor id="deprecated_1_deprecated000002"/>Member <ref refid="class_deprecated_1a1d5f6803e72c625727e7083d1722dbf9" kindref="member">Deprecated::deprecated</ref> ()</term>
+ <term>Member <ref refid="class_deprecated_1a1d5f6803e72c625727e7083d1722dbf9" kindref="member">Deprecated::deprecated</ref> ()</term>
</varlistentry>
<listitem>
- <para>No not use this function anymore. </para>
+ <para><anchor id="deprecated_1_deprecated000002"/>No not use this function anymore. </para>
</listitem>
</variablelist>
</para>
diff --git a/testing/009/reminders.xml b/testing/009/reminders.xml
index a5c5560..f848e3c 100644
--- a/testing/009/reminders.xml
+++ b/testing/009/reminders.xml
@@ -9,16 +9,16 @@
<para>
<variablelist>
<varlistentry>
- <term><anchor id="reminders_1_reminders000001"/>Class <ref refid="class_reminder" kindref="compound">Reminder</ref></term>
+ <term>Class <ref refid="class_reminder" kindref="compound">Reminder</ref></term>
</varlistentry>
<listitem>
- <para>A reminder </para>
+ <para><anchor id="reminders_1_reminders000001"/>A reminder </para>
</listitem>
<varlistentry>
- <term><anchor id="reminders_1_reminders000002"/>Member <ref refid="class_reminder_1a173b5218bb11287b0e86a550d9f0728d" kindref="member">Reminder::reminder</ref> ()</term>
+ <term>Member <ref refid="class_reminder_1a173b5218bb11287b0e86a550d9f0728d" kindref="member">Reminder::reminder</ref> ()</term>
</varlistentry>
<listitem>
- <para>Need to rework this before the next release. </para>
+ <para><anchor id="reminders_1_reminders000002"/>Need to rework this before the next release. </para>
</listitem>
</variablelist>
</para>
diff --git a/testing/009/test.xml b/testing/009/test.xml
index e206440..828316d 100644
--- a/testing/009/test.xml
+++ b/testing/009/test.xml
@@ -9,16 +9,16 @@
<para>
<variablelist>
<varlistentry>
- <term><anchor id="test_1_test000001"/>Class <ref refid="class_test" kindref="compound">Test</ref></term>
+ <term>Class <ref refid="class_test" kindref="compound">Test</ref></term>
</varlistentry>
<listitem>
- <para>This is part of testing </para>
+ <para><anchor id="test_1_test000001"/>This is part of testing </para>
</listitem>
<varlistentry>
- <term><anchor id="test_1_test000002"/>Member <ref refid="class_test_1a9fc54b716f326514a4c5f434137f4fc0" kindref="member">Test::test</ref> ()</term>
+ <term>Member <ref refid="class_test_1a9fc54b716f326514a4c5f434137f4fc0" kindref="member">Test::test</ref> ()</term>
</varlistentry>
<listitem>
- <para>more things to test. </para>
+ <para><anchor id="test_1_test000002"/>more things to test. </para>
</listitem>
</variablelist>
</para>
diff --git a/testing/009/todo.xml b/testing/009/todo.xml
index 88d050e..394f07d 100644
--- a/testing/009/todo.xml
+++ b/testing/009/todo.xml
@@ -9,16 +9,16 @@
<para>
<variablelist>
<varlistentry>
- <term><anchor id="todo_1_todo000001"/>Class <ref refid="class_todo" kindref="compound">Todo</ref></term>
+ <term>Class <ref refid="class_todo" kindref="compound">Todo</ref></term>
</varlistentry>
<listitem>
- <para>This still needs to be done. </para>
+ <para><anchor id="todo_1_todo000001"/>This still needs to be done. </para>
</listitem>
<varlistentry>
- <term><anchor id="todo_1_todo000002"/>Member <ref refid="class_todo_1a9e70ec9176ac4c1b20e011b4daddc9d8" kindref="member">Todo::todo</ref> ()</term>
+ <term>Member <ref refid="class_todo_1a9e70ec9176ac4c1b20e011b4daddc9d8" kindref="member">Todo::todo</ref> ()</term>
</varlistentry>
<listitem>
- <para>more things to do here </para>
+ <para><anchor id="todo_1_todo000002"/>more things to do here </para>
</listitem>
</variablelist>
</para>
diff --git a/testing/012/citelist.xml b/testing/012/citelist.xml
index 96b94a3..f415968 100644
--- a/testing/012/citelist.xml
+++ b/testing/012/citelist.xml
@@ -9,7 +9,7 @@
<para>
<variablelist>
<varlistentry>
- <term><anchor id="_1CITEREF_knuth79"/>[1]</term>
+ <term><anchor id="citelist_1CITEREF_knuth79"/>[1]</term>
</varlistentry>
<listitem>
<para>Donald<nonbreakablespace/>E. Knuth. <emphasis>Tex and Metafont, New Directions in Typesetting</emphasis>. American Mathematical Society and Digital Press, Stanford, 1979.</para>
diff --git a/testing/README.txt b/testing/README.txt
index 4988a07..39b2345 100644
--- a/testing/README.txt
+++ b/testing/README.txt
@@ -7,7 +7,7 @@ has the same 3 digit number. The directory contains one or more reference
files that are compared against the XML output produced by doxygen. If the
result is the same, there is no regression and the test passes. If there is a
difference the test fails and the difference (in diff -u format) will be shown.
-It is also possible to see whether or not the test can be built to an xhtml set
+It is also possible to see whether or not the test can be built to a xhtml set
of files (and tested against a DTD), it is also possible to create a pdf file
for each test to see if the LaTeX / pdf generation is possible.
@@ -17,6 +17,8 @@ optional parameters:
--doxygen [DOXYGEN] path/name of the doxygen executable
--xmllint [XMLLINT] path/name of the xmllint executable
--id IDS [IDS ...] id of the test to perform
+ --start_id START_ID run tests starting with number n
+ --end_id END_ID run tests ending with number n
--all perform all tests
--inputdir [INPUTDIR]
input directory containing the tests
@@ -24,13 +26,15 @@ optional parameters:
output directory to write the doxygen output to
--noredir disable redirection of doxygen warnings
--xml create xml output and check
+ --rtf create rtf output
+ --docbook create docbook output and check with xmllint
--xhtml create xhtml output and check with xmllint
--pdf create LaTeX output and create pdf from it
+ --subdirs use the configuration parameter CREATE_SUBDIRS=YES
--keep keep result directories
- --cfg CFGS [CFGS ...]
- run test with extra doxygen configuration settings
+ --cfg CFGS [CFGS ...] run test with extra doxygen configuration settings
(the option may be specified multiple times
-In case neither --xml, --pdf or --xhtml is used the default is set to --xml.
+In case neither --xml, --pdf, --rtf, --docbook or --xhtml is used the default is set to --xml.
The runtest.pl has the following dependencies on 3rd party tools:
- python to run the script
diff --git a/testing/runtests.py b/testing/runtests.py
index fa74627..452c36e 100644
--- a/testing/runtests.py
+++ b/testing/runtests.py
@@ -43,6 +43,28 @@ class Tester:
rtnmsg += o
return rtnmsg
+ def cleanup_xmllint_docbook(self,errmsg):
+ # For future work, first get everything valid XML
+ msg = self.cleanup_xmllint(errmsg).split('\n')
+ rtnmsg = ""
+ cnt = 0
+ for o in msg:
+ if (o):
+ if (cnt):
+ cnt -= 1
+ pass
+ elif (o.endswith("does not validate")):
+ pass
+ elif (o.find("no DTD found!")!=-1):
+ pass
+ elif (o.find("is not an NCName")!=-1):
+ cnt = 2
+ else:
+ if (rtnmsg):
+ rtnmsg += '\n'
+ rtnmsg += o
+ return rtnmsg
+
def get_config(self):
config = {}
with open(self.args.inputdir+'/'+self.test,'r') as f:
@@ -53,7 +75,7 @@ class Tester:
value = m.group('value')
if (key=='config'):
value = value.replace('$INPUTDIR',self.args.inputdir)
- #print('key=%s value=%s' % (key,value))
+ # print('key=%s value=%s' % (key,value))
config.setdefault(key, []).append(value)
return config
@@ -74,6 +96,16 @@ class Tester:
print('XML_OUTPUT=%s/out' % self.test_out, file=f)
else:
print('GENERATE_XML=NO', file=f)
+ if (self.args.rtf):
+ print('GENERATE_RTF=YES', file=f)
+ print('RTF_OUTPUT=%s/rtf' % self.test_out, file=f)
+ else:
+ print('GENERATE_RTF=NO', file=f)
+ if (self.args.docbook):
+ print('GENERATE_DOCBOOK=YES', file=f)
+ print('DOCBOOK_OUTPUT=%s/docbook' % self.test_out, file=f)
+ else:
+ print('GENERATE_DOCBOOK=NO', file=f)
if (self.args.xhtml):
print('GENERATE_HTML=YES', file=f)
# HTML_OUTPUT can also be set locally
@@ -82,6 +114,8 @@ class Tester:
if (self.args.pdf):
print('GENERATE_LATEX=YES', file=f)
print('LATEX_OUTPUT=%s/latex' % self.test_out, file=f)
+ if self.args.subdirs:
+ print('CREATE_SUBDIRS=YES', file=f)
if (self.args.cfgs):
for cfg in list(itertools.chain.from_iterable(self.args.cfgs)):
if cfg.find('=') == -1:
@@ -103,7 +137,7 @@ class Tester:
redir=''
if os.system('%s %s/Doxyfile %s' % (self.args.doxygen,self.test_out,redir))!=0:
- print('Error: failed to run %s on %s/Doxyfile' % (self.args.doxygen,self.test_out));
+ print('Error: failed to run %s on %s/Doxyfile' % (self.args.doxygen,self.test_out))
sys.exit(1)
# update the reference data for this test
@@ -146,6 +180,8 @@ class Tester:
failed_xml=False
failed_html=False
failed_latex=False
+ failed_docbook=False
+ failed_rtf=False
msg = ()
# look for files to check against the reference
if self.args.xml:
@@ -155,8 +191,14 @@ class Tester:
check_file='%s/out/%s' % (self.test_out,check)
# check if the file we need to check is actually generated
if not os.path.isfile(check_file):
- msg += ('Non-existing file %s after \'check:\' statement' % check_file,)
- break
+ # try with sub dirs
+ check_file = glob.glob('%s/out/*/*/%s' % (self.test_out,check))
+ if not check_file:
+ check_file='%s/out/%s' % (self.test_out,check)
+ msg += ('Non-existing file %s after \'check:\' statement' % check_file,)
+ break
+ else:
+ check_file = check_file[0]
# convert output to canonical form
data = os.popen('%s --format --noblanks --nowarning %s' % (self.args.xmllint,check_file)).read()
if data:
@@ -177,6 +219,34 @@ class Tester:
xml_output='%s/out' % self.test_out
shutil.rmtree(xml_output,ignore_errors=True)
+ if (self.args.rtf):
+ # no tests defined yet
+ pass
+
+ if (self.args.docbook):
+ docbook_output='%s/docbook' % self.test_out
+ if (sys.platform == 'win32'):
+ redirx=' 2> %s/temp >nul:'%docbook_output
+ else:
+ redirx='2>%s/temp >/dev/null'%docbook_output
+ # For future work, first get everything valid XML
+ # exe_string = '%s --relaxng db/docbook.rng --nonet --postvalid %s/*xml %s % (self.args.xmllint,docbook_output,redirx)
+ tests = []
+ tests.append(glob.glob('%s/*.xml' % (docbook_output)))
+ tests.append(glob.glob('%s/*/*/*.xml' % (docbook_output)))
+ tests = ' '.join(list(itertools.chain.from_iterable(tests))).replace(self.args.outputdir +'/','').replace('\\','/')
+ exe_string = '%s --nonet --postvalid %s %s' % (self.args.xmllint,tests,redirx)
+ exe_string += ' %s more "%s/temp"' % (separ,docbook_output)
+
+ failed_docbook=False
+ xmllint_out = os.popen(exe_string).read()
+ xmllint_out = self.cleanup_xmllint_docbook(xmllint_out)
+ if xmllint_out:
+ msg += (xmllint_out,)
+ failed_docbook=True
+ elif not self.args.keep:
+ shutil.rmtree(docbook_output,ignore_errors=True)
+
if (self.args.xhtml):
html_output='%s/html' % self.test_out
if (sys.platform == 'win32'):
@@ -212,7 +282,7 @@ class Tester:
elif not self.args.keep:
shutil.rmtree(latex_output,ignore_errors=True)
- if failed_xml or failed_html or failed_latex:
+ if failed_xml or failed_html or failed_latex or failed_docbook or failed_rtf:
testmgr.ok(False,self.test_name,msg)
return
@@ -280,8 +350,12 @@ def main():
parser.add_argument('--xmllint',nargs='?',default='xmllint',help=
'path/name of the xmllint executable')
parser.add_argument('--id',nargs='+',dest='ids',action='append',type=int,help=
- 'run test with number n only (the option may be specified run test with '
- 'number n only (the option may be specified')
+ 'run test with number n only (the option can be specified to run test with '
+ 'number n only (the option can be specified multiple times')
+ parser.add_argument('--start_id',dest='start_id',type=int,help=
+ 'run tests starting with number n')
+ parser.add_argument('--end_id',dest='end_id',type=int,help=
+ 'run tests ending with number n')
parser.add_argument('--all',help=
'can be used in combination with -updateref to update the reference files '
'for all tests.',action="store_true")
@@ -293,10 +367,16 @@ def main():
'disable redirection of doxygen warnings',action="store_true")
parser.add_argument('--xml',help='create xml output and check',
action="store_true")
+ parser.add_argument('--rtf',help=
+ 'create rtf output',action="store_true")
+ parser.add_argument('--docbook',help=
+ 'create docbook output and check with xmllint',action="store_true")
parser.add_argument('--xhtml',help=
'create xhtml output and check with xmllint',action="store_true")
parser.add_argument('--pdf',help='create LaTeX output and create pdf from it',
action="store_true")
+ parser.add_argument('--subdirs',help='use the configuration parameter CREATE_SUBDIRS=YES',
+ action="store_true")
parser.add_argument('--keep',help='keep result directories',
action="store_true")
parser.add_argument('--cfg',nargs='+',dest='cfgs',action='append',help=
@@ -306,7 +386,7 @@ def main():
args = parser.parse_args(test_flags + sys.argv[1:])
# sanity check
- if (not args.xml) and (not args.pdf) and (not args.xhtml):
+ if (not args.xml) and (not args.pdf) and (not args.xhtml) and (not args.docbook and (not args.rtf)):
args.xml=True
if (not args.updateref is None) and (args.ids is None) and (args.all is None):
parser.error('--updateref requires either --id or --all')
@@ -314,15 +394,26 @@ def main():
starting_directory = os.getcwd()
os.chdir(args.inputdir)
# find the tests to run
- if args.ids: # test ids are given by user
- tests = []
+ tests = []
+ if args.start_id:
+ if args.end_id:
+ for id in range(args.start_id, args.end_id + 1):
+ tests.append(glob.glob('%s_*'%id))
+ tests.append(glob.glob('0%s_*'%id))
+ tests.append(glob.glob('00%s_*'%id))
+ else:
+ parser.error('--start_id requires --end_id')
+ elif args.end_id:
+ parser.error('--end_id requires --start_id')
+ if args.ids: # test ids are given by user
for id in list(itertools.chain.from_iterable(args.ids)):
tests.append(glob.glob('%s_*'%id))
tests.append(glob.glob('0%s_*'%id))
tests.append(glob.glob('00%s_*'%id))
- tests = list(itertools.chain.from_iterable(tests))
- else: # find all tests
+ if (not args.ids and not args.start_id): # find all tests
tests = glob.glob('[0-9][0-9][0-9]_*')
+ else:
+ tests = list(itertools.chain.from_iterable(tests))
os.chdir(starting_directory)
# create test manager to run the tests