Commit cfa9d4d5 authored by dimitri's avatar dimitri

Release-1.5.3

parent 54e919c7
DOXYGEN Version 1.5.2-20070719 DOXYGEN Version 1.5.3
Please read the installation section of the manual Please read the installation section of the manual
(http://www.doxygen.org/install.html) for instructions. (http://www.doxygen.org/install.html) for instructions.
-------- --------
Dimitri van Heesch (19 July 2007) Dimitri van Heesch (27 July 2007)
DOXYGEN Version 1.5.2_20070719 DOXYGEN Version 1.5.3
Please read INSTALL for compilation instructions. Please read INSTALL for compilation instructions.
...@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives. ...@@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives.
Enjoy, Enjoy,
Dimitri van Heesch (dimitri@stack.nl) (19 July 2007) Dimitri van Heesch (dimitri@stack.nl) (27 July 2007)
...@@ -17,10 +17,10 @@ ...@@ -17,10 +17,10 @@
doxygen_version_major=1 doxygen_version_major=1
doxygen_version_minor=5 doxygen_version_minor=5
doxygen_version_revision=2 doxygen_version_revision=3
#NOTE: Setting version_mmn to "NO" will omit mmn info from the package. #NOTE: Setting version_mmn to "NO" will omit mmn info from the package.
doxygen_version_mmn=20070719 doxygen_version_mmn=NO
bin_dirs=`echo $PATH | sed -e "s/:/ /g"` bin_dirs=`echo $PATH | sed -e "s/:/ /g"`
......
...@@ -783,7 +783,7 @@ See section \ref memgroup for an example. ...@@ -783,7 +783,7 @@ See section \ref memgroup for an example.
\ref cmdendcond "\\endcond" command, which is typically found in \ref cmdendcond "\\endcond" command, which is typically found in
another comment block. The main purpose of this pair of another comment block. The main purpose of this pair of
commands is to (conditionally) exclude part of a file from processing commands is to (conditionally) exclude part of a file from processing
(traditionally this could only be achieved using C processor commands). (in older version of doxygen this could only be achieved using C preprocessor commands).
The section between \\cond and \\endcond commands can be included by The section between \\cond and \\endcond commands can be included by
adding its section label to the \ref cfg_enabled_sections "ENABLED_SECTIONS" adding its section label to the \ref cfg_enabled_sections "ENABLED_SECTIONS"
...@@ -838,8 +838,8 @@ class Implementation : public Intf ...@@ -838,8 +838,8 @@ class Implementation : public Intf
/// @endcond /// @endcond
\endverbatim \endverbatim
The output will be different depending on whether \c ENABLED_SECTIONS The output will be different depending on whether or not \c ENABLED_SECTIONS
is empty, \c TEST, \c DEV, or \c DEV \c TEST. contains \c TEST, or \c DEV
<hr> <hr>
\section cmddate \\date { date description } \section cmddate \\date { date description }
......
...@@ -100,6 +100,7 @@ followed by the descriptions of the tags grouped by category. ...@@ -100,6 +100,7 @@ followed by the descriptions of the tags grouped by category.
\refitem cfg_external_groups EXTERNAL_GROUPS \refitem cfg_external_groups EXTERNAL_GROUPS
\refitem cfg_extra_packages EXTRA_PACKAGES \refitem cfg_extra_packages EXTRA_PACKAGES
\refitem cfg_extract_all EXTRACT_ALL \refitem cfg_extract_all EXTRACT_ALL
\refitem cfg_extract_anon_nspaces EXTRACT_ANON_NSPACES
\refitem cfg_extract_local_classes EXTRACT_LOCAL_CLASSES \refitem cfg_extract_local_classes EXTRACT_LOCAL_CLASSES
\refitem cfg_extract_local_methods EXTRACT_LOCAL_METHODS \refitem cfg_extract_local_methods EXTRACT_LOCAL_METHODS
\refitem cfg_extract_private EXTRACT_PRIVATE \refitem cfg_extract_private EXTRACT_PRIVATE
...@@ -136,6 +137,7 @@ followed by the descriptions of the tags grouped by category. ...@@ -136,6 +137,7 @@ followed by the descriptions of the tags grouped by category.
\refitem cfg_hide_undoc_members HIDE_UNDOC_MEMBERS \refitem cfg_hide_undoc_members HIDE_UNDOC_MEMBERS
\refitem cfg_hide_undoc_relations HIDE_UNDOC_RELATIONS \refitem cfg_hide_undoc_relations HIDE_UNDOC_RELATIONS
\refitem cfg_html_align_members HTML_ALIGN_MEMBERS \refitem cfg_html_align_members HTML_ALIGN_MEMBERS
\refitem cfg_html_dynamic_sections HTML_DYNAMIC_SECTIONS
\refitem cfg_html_footer HTML_FOOTER \refitem cfg_html_footer HTML_FOOTER
\refitem cfg_html_header HTML_HEADER \refitem cfg_html_header HTML_HEADER
\refitem cfg_html_output HTML_OUTPUT \refitem cfg_html_output HTML_OUTPUT
...@@ -548,6 +550,14 @@ followed by the descriptions of the tags grouped by category. ...@@ -548,6 +550,14 @@ followed by the descriptions of the tags grouped by category.
If set to NO only classes defined in header files are included. Does not If set to NO only classes defined in header files are included. Does not
have any effect for Java sources. have any effect for Java sources.
\anchor cfg_extract_anon_nspaces
<dt>\c EXTRACT_ANON_NSPACES <dd>
\addindex EXTRACT_ANON_NSPACES
If this flag is set to YES, the members of anonymous namespaces will be extracted
and appear in the documentation as a namespace called 'anonymous_namespace{file}',
where file will be replaced with the base name of the file that contains the anonymous
namespace. By default anonymous namespace are hidden.
\anchor cfg_extract_local_methods \anchor cfg_extract_local_methods
<dt>\c EXTRACT_LOCAL_METHODS <dd> <dt>\c EXTRACT_LOCAL_METHODS <dd>
\addindex EXTRACT_LOCAL_METHODS \addindex EXTRACT_LOCAL_METHODS
...@@ -1128,6 +1138,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" ...@@ -1128,6 +1138,7 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn"
Setting this tag to \c NO will become obsolete in the future, since I only Setting this tag to \c NO will become obsolete in the future, since I only
intent to support and test the aligned representation. intent to support and test the aligned representation.
\anchor cfg_generate_htmlhelp \anchor cfg_generate_htmlhelp
<dt>\c GENERATE_HTMLHELP <dd> <dt>\c GENERATE_HTMLHELP <dd>
\addindex GENERATE_HTMLHELP \addindex GENERATE_HTMLHELP
...@@ -1147,6 +1158,15 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn" ...@@ -1147,6 +1158,15 @@ FILE_VERSION_INFO = "cleartool desc -fmt \%Vn"
and you can search for words in the documentation. and you can search for words in the documentation.
The HTML workshop also contains a viewer for compressed HTML files. The HTML workshop also contains a viewer for compressed HTML files.
\anchor cfg_html_dynamic_sections
<dt>\c HTML_DYNAMIC_SECTIONS <dd>
\addindex HTML_DYNAMIC_SECTIONS
If the \c HTML_DYNAMIC_SECTIONS tag is set to \c YES then the generated HTML
documentation will contain sections that can be hidden and shown after the
page has loaded. For this to work a browser that supports
JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
\anchor cfg_chm_file \anchor cfg_chm_file
<dt>\c CHM_FILE <dd> <dt>\c CHM_FILE <dd>
\addindex CHM_FILE \addindex CHM_FILE
......
...@@ -24,15 +24,21 @@ needs to end up in the generated documentation. For Python code there is ...@@ -24,15 +24,21 @@ needs to end up in the generated documentation. For Python code there is
a different comment convention, which can be found in section a different comment convention, which can be found in section
\ref pythonblocks \ref pythonblocks
For each code item there are two types of descriptions, which together For each code item there are two (or in some cases three) types of descriptions,
form the documentation: a \e brief description and \e detailed which together form the documentation: a \e brief description and \e detailed
description, both are optional. description, both are optional. For methods and functions there is also a third
Having more than one brief or detailed description however, is type of description, the so called "in body" description, which consists of
not allowed. the concatenation of all comment blocks found within the body of the method or function.
Having more than one brief or detailed description is allowed (but not recommended,
as the order in which the descriptions will appear is not specified).
As the name suggest, a brief description is As the name suggest, a brief description is
a short one-liner, whereas the detailed description provides longer, a short one-liner, whereas the detailed description provides longer,
more detailed documentation. more detailed documentation. An "in body" description can also act as a detailed
description or can describe a collection of implementation details.
For the HTML output brief descriptions are also
use to provide tooltips at places where an item is referenced.
There are several ways to mark a comment block as a detailed description: There are several ways to mark a comment block as a detailed description:
<ol> <ol>
...@@ -87,6 +93,15 @@ or ...@@ -87,6 +93,15 @@ or
Some people like to make their comment blocks more visible in the Some people like to make their comment blocks more visible in the
documentation. For this purpose you can use the following: documentation. For this purpose you can use the following:
\verbatim
/************************************************
* ... text
***********************************************/
\endverbatim
or
\verbatim \verbatim
///////////////////////////////////////////////// /////////////////////////////////////////////////
/// ... text ... /// ... text ...
......
...@@ -30,8 +30,8 @@ ...@@ -30,8 +30,8 @@
<li>Automatically generates class and collaboration diagrams in HTML (as clickable <li>Automatically generates class and collaboration diagrams in HTML (as clickable
image maps) and \f$\mbox{\LaTeX}\f$ (as Encapsulated PostScript images). image maps) and \f$\mbox{\LaTeX}\f$ (as Encapsulated PostScript images).
<li>Uses the dot tool of the Graphviz tool kit to generate <li>Uses the dot tool of the Graphviz tool kit to generate
include dependency graphs, collaboration diagrams, and include dependency graphs, collaboration diagrams, call graphs, directory structure
graphical class hierarchy graphs. graphs, and graphical class hierarchy graphs.
<li>Flexible comment placement: Allows you to put documentation in the <li>Flexible comment placement: Allows you to put documentation in the
header file (before the header file (before the
declaration of an entity), source file (before the definition of an entity) declaration of an entity), source file (before the definition of an entity)
...@@ -78,14 +78,14 @@ ...@@ -78,14 +78,14 @@
<li>Can cope with large projects easily. <li>Can cope with large projects easily.
</UL> </UL>
Although doxygen can be used in any C or C++ project, Although doxygen can now be used in any project written in a language that is
initially it was specifically designed to be used for projects that make supported by doxygen, initially it was specifically designed to be used for projects
use of Troll Tech's that make use of Troll Tech's
<A HREF="http://www.trolltech.com/products/qt.html">Qt toolkit</A>. I have tried to make doxygen <A HREF="http://www.trolltech.com/products/qt.html">Qt toolkit</A>. I have tried to
`Qt-compatible'. That is: Doxygen can read the documentation contained in make doxygen `Qt-compatible'. That is: Doxygen can read the documentation contained in
the Qt source code and create a class browser that looks very similar to the the Qt source code and create a class browser that looks quite similar to the
one that is generated by Troll Tech. Doxygen understands the C++ extensions one that is generated by Troll Tech. Doxygen understands the C++ extensions
used by Qt such as signals and slots. used by Qt such as signals and slots and many of the markup commands used in the Qt sources.
Doxygen can also automatically generate links to existing documentation Doxygen can also automatically generate links to existing documentation
that was generated with Doxygen or with Qt's non-public class browser that was generated with Doxygen or with Qt's non-public class browser
......
...@@ -49,8 +49,10 @@ The following output formats are \e indirectly supported by doxygen: ...@@ -49,8 +49,10 @@ The following output formats are \e indirectly supported by doxygen:
<dt><b>PDF</b>\htmlonly &nbsp;&nbsp;&nbsp;\endhtmlonly <dt><b>PDF</b>\htmlonly &nbsp;&nbsp;&nbsp;\endhtmlonly
<dd>Generated from the \f$\mbox{\LaTeX}\f$ output by <dd>Generated from the \f$\mbox{\LaTeX}\f$ output by
running <code>make pdf</code> in the output directory. running <code>make pdf</code> in the output directory.
In order to get hyperlinks in the PDF file, To improve the PDF output, you typically would want to enable the use
\c PDF_HYPERLINKS should be set to \c YES in the configuration file. of \c pdflatex by setting \ref cfg_use_pdflatex "USE_PDFLATEX" to \c YES in the
configuration file. In order to get hyperlinks in the PDF file you also need to enable
\ref cfg_pdf_hyperlinks "PDF_HYPERLINKS".
</dl> </dl>
*/ */
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm /*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*
* Changed so as no longer to depend on Colin Plumb's `usual.h' header
* definitions; now uses stuff from dpkg's config.h.
* - Ian Jackson <ian@chiark.greenend.org.uk>.
* Still in the public domain.
*/ */
#include "config.h"
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All #include <string.h> /* for memcpy() */
rights reserved. #include <sys/types.h> /* for stupid systems */
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "md5_loc.h"
#include "md5.h" #include "md5.h"
/* Constants for MD5Transform routine. void
*/ MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform (UINT4 [4], const unsigned char [64]);
static void Encode(unsigned char *, UINT4 *, unsigned int);
static void Decode (UINT4 *, const unsigned char *, unsigned int);
static void MD5_memcpy (POINTER, POINTER, unsigned int);
static void MD5_memset (POINTER, int, unsigned int);
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits. int g_bigEndian = 0;
*/ int g_endianessDetected = 0;
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. static void
Rotation is separate from addition to prevent recomputation. detectEndianess()
*/ {
#define FF(a, b, c, d, x, s, ac) { \ int nl = 0x12345678;
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ short ns = 0x1234;
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \ unsigned char *p = (unsigned char *)(&nl);
} unsigned char *sp = (unsigned char *)(&ns);
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ if (g_endianessDetected) return;
(a) = ROTATE_LEFT ((a), (s)); \ if ( p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 )
(a) += (b); \ {
g_bigEndian = 1;
} }
#define HH(a, b, c, d, x, s, ac) { \ else if ( p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] == 0x12 )
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ {
(a) = ROTATE_LEFT ((a), (s)); \ g_bigEndian = 0;
(a) += (b); \
} }
#define II(a, b, c, d, x, s, ac) { \ else
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ {
(a) = ROTATE_LEFT ((a), (s)); \ g_bigEndian = *sp != 0x12;
(a) += (b); \
} }
/* MD5 initialization. Begins an MD5 operation, writing a new context. g_endianessDetected=1;
}
static void
byteSwap(UWORD32 *buf, unsigned words)
{
md5byte *p;
if (!g_bigEndian) return;
p = (md5byte *)buf;
do {
*buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
((unsigned)p[1] << 8 | p[0]);
p += 4;
} while (--words);
}
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/ */
void MD5Init (MD5_CTX *context) void
MD5Init(struct MD5Context *ctx)
{ {
context->count[0] = context->count[1] = 0; detectEndianess();
/* Load magic initialization constants. ctx->buf[0] = 0x67452301;
*/ ctx->buf[1] = 0xefcdab89;
context->state[0] = 0x67452301; ctx->buf[2] = 0x98badcfe;
context->state[1] = 0xefcdab89; ctx->buf[3] = 0x10325476;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476; ctx->bytes[0] = 0;
ctx->bytes[1] = 0;
} }
/* MD5 block update operation. Continues an MD5 message-digest /*
operation, processing another message block, and updating the * Update context to reflect the concatenation of another buffer full
context. * of bytes.
*/ */
void MD5Update (MD5_CTX *context, const unsigned char *input, unsigned int inputLen) void
MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
{ {
unsigned int i, index, partLen; UWORD32 t;
/* Compute number of bytes mod 64 */ /* Update byte count */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
t = ctx->bytes[0];
/* Update number of bits */ if ((ctx->bytes[0] = t + len) < t)
if ((context->count[0] += ((UINT4)inputLen << 3)) ctx->bytes[1]++; /* Carry from low to high */
< ((UINT4)inputLen << 3))
context->count[1]++; t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
context->count[1] += ((UINT4)inputLen >> 29); if (t > len) {
memcpy((md5byte *)ctx->in + 64 - t, buf, len);
partLen = 64 - index; return;
}
/* Transform as many times as possible. /* First chunk is an odd size */
*/ memcpy((md5byte *)ctx->in + 64 - t, buf, t);
if (inputLen >= partLen) { byteSwap(ctx->in, 16);
MD5_memcpy MD5Transform(ctx->buf, ctx->in);
((POINTER)&context->buffer[index], (POINTER)input, partLen); buf += t;
MD5Transform (context->state, context->buffer); len -= t;
for (i = partLen; i + 63 < inputLen; i += 64) /* Process data in 64-byte chunks */
MD5Transform (context->state, &input[i]); while (len >= 64) {
memcpy(ctx->in, buf, 64);
index = 0; byteSwap(ctx->in, 16);
} MD5Transform(ctx->buf, ctx->in);
else buf += 64;
i = 0; len -= 64;
}
/* Buffer remaining input */
MD5_memcpy /* Handle any remaining bytes of data. */
((POINTER)&context->buffer[index], (POINTER)&input[i], memcpy(ctx->in, buf, len);
inputLen-i);
} }
/* MD5 finalization. Ends an MD5 message-digest operation, writing the /*
the message digest and zeroizing the context. * Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/ */
void MD5Final (MD5_CTX *context, unsigned char digest[16]) void
MD5Final(md5byte digest[16], struct MD5Context *ctx)
{ {
unsigned char bits[8]; int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
unsigned int index, padLen; md5byte *p = (md5byte *)ctx->in + count;
/* Save number of bits */ /* Set the first char of padding to 0x80. There is always room. */
Encode (bits, context->count, 8); *p++ = 0x80;
/* Pad out to 56 mod 64. /* Bytes of padding needed to make 56 bytes (-8..55) */
*/ count = 56 - 1 - count;
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index); if (count < 0) { /* Padding forces an extra block */
MD5Update (context, PADDING, padLen); memset(p, 0, count + 8);
byteSwap(ctx->in, 16);
/* Append length (before padding) */ MD5Transform(ctx->buf, ctx->in);
MD5Update (context, bits, 8); p = (md5byte *)ctx->in;
count = 56;
/* Store state in digest */ }
Encode (digest, context->state, 16); memset(p, 0, count);
byteSwap(ctx->in, 14);
/* Zeroize sensitive information.
*/ /* Append length in bits and transform */
MD5_memset ((POINTER)context, 0, sizeof (*context)); ctx->in[14] = ctx->bytes[0] << 3;
ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
MD5Transform(ctx->buf, ctx->in);
byteSwap(ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
} }
#ifndef ASM_MD5
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f,w,x,y,z,in,s) \
(w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void
MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
{
register UWORD32 a, b, c, d;
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
#endif
void MD5Buffer (const unsigned char *buf,unsigned int len,unsigned char sig[16]) void MD5Buffer (const unsigned char *buf,unsigned int len,unsigned char sig[16])
{ {
MD5_CTX md5; struct MD5Context md5;
MD5Init(&md5); MD5Init(&md5);
MD5Update(&md5,buf,len); MD5Update(&md5,buf,len);
MD5Final(&md5,sig); MD5Final(sig,&md5);
} }
#define HEX_STRING "0123456789abcdef" /* to convert to hex */ #define HEX_STRING "0123456789abcdef" /* to convert to hex */
...@@ -195,7 +294,7 @@ void MD5SigToString(unsigned char signature[16],char *str,int len) ...@@ -195,7 +294,7 @@ void MD5SigToString(unsigned char signature[16],char *str,int len)
for (sig_p = (unsigned char *)signature; for (sig_p = (unsigned char *)signature;
sig_p < (unsigned char *)signature + 16; sig_p < (unsigned char *)signature + 16;
sig_p++) sig_p++)
{ {
high = *sig_p / 16; high = *sig_p / 16;
low = *sig_p % 16; low = *sig_p % 16;
...@@ -212,141 +311,4 @@ void MD5SigToString(unsigned char signature[16],char *str,int len) ...@@ -212,141 +311,4 @@ void MD5SigToString(unsigned char signature[16],char *str,int len)
} }
} }
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (UINT4 state[4], const unsigned char block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (UINT4 *output, const unsigned char *input, unsigned int len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (POINTER output, int value, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}
/* MD5.H - header file for MD5C.C /*
* This is the header file for the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*
* Changed so as no longer to depend on Colin Plumb's `usual.h'
* header definitions; now uses stuff from dpkg's config.h
* - Ian Jackson <ian@chiark.greenend.org.uk>.
* Still in the public domain.
*/ */
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All #ifndef MD5_H
rights reserved. #define MD5_H
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#ifndef _MD5_H_
#define _MD5_H_
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "md5_loc.h" #include "md5_loc.h"
/* MD5 context. */ #define md5byte unsigned char
typedef struct {
UINT4 state[4]; /* state (ABCD) */ //#if SIZEOF_UNSIGNED_LONG==4
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ //# define UWORD32 unsigned long
unsigned char buffer[64]; /* input buffer */ //#elif SIZEOF_UNSIGNED_INT==4
} MD5_CTX; //#else
//# error I do not know what to use for a UWORD32.
void MD5Init(MD5_CTX *ctx); //#endif
void MD5Update (MD5_CTX *ctx, const unsigned char *buf, unsigned int len);
void MD5Final (MD5_CTX *ctx, unsigned char sig[16]); struct MD5Context {
UWORD32 buf[4];
UWORD32 bytes[2];
UWORD32 in[16];
};
void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
void MD5Final(unsigned char digest[16], struct MD5Context *context);
void MD5Buffer (const unsigned char *buf,unsigned int len,unsigned char sig[16]); void MD5Buffer (const unsigned char *buf,unsigned int len,unsigned char sig[16]);
void MD5SigToString(unsigned char sig[16],char *str,int len); void MD5SigToString(unsigned char sig[16],char *str,int len);
...@@ -49,4 +54,4 @@ void MD5SigToString(unsigned char sig[16],char *str,int len); ...@@ -49,4 +54,4 @@ void MD5SigToString(unsigned char sig[16],char *str,int len);
} }
#endif #endif
#endif #endif /* !MD5_H */
/* GLOBAL.H - RSAREF types and constants */
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
Inc., created 1991. All rights reserved.
*/
#ifndef _MD5LOC_H #ifndef _MD5LOC_H
#define _MD5LOC_H #define _MD5LOC_H
/* POINTER defines a generic pointer type */ # define UWORD32 unsigned int
typedef unsigned char *POINTER;
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
/* UINT4 defines a four byte word */
typedef unsigned long int UINT4;
#ifndef NULL_PTR
#define NULL_PTR ((POINTER)0)
#endif #endif
#ifndef UNUSED_ARG
#define UNUSED_ARG(x) x = *(&x);
#endif
#endif /* end _GLOBAL_H_ */
...@@ -59,6 +59,7 @@ public: ...@@ -59,6 +59,7 @@ public:
type *pop() { return (type *)QGList::takeFirst(); } type *pop() { return (type *)QGList::takeFirst(); }
bool remove() { return QGList::removeFirst(); } bool remove() { return QGList::removeFirst(); }
void clear() { QGList::clear(); } void clear() { QGList::clear(); }
type *bottom() const { return (type *)QGList::clast(); }
type *top() const { return (type *)QGList::cfirst(); } type *top() const { return (type *)QGList::cfirst(); }
operator type *() const { return (type *)QGList::cfirst(); } operator type *() const { return (type *)QGList::cfirst(); }
type *current() const { return (type *)QGList::cfirst(); } type *current() const { return (type *)QGList::cfirst(); }
......
...@@ -222,7 +222,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name) ...@@ -222,7 +222,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name)
ltype = ltype.right(ltype.length()-6); ltype = ltype.right(ltype.length()-6);
} }
if (ltype.isEmpty() || lname.isEmpty()) return; if (ltype.isEmpty() || lname.isEmpty()) return;
DBG_CTX((stderr,"** addVariable trying: type=%s name=%s g_currentDefinition=%s\n", DBG_CTX((stderr,"** addVariable trying: type='%s' name='%s' g_currentDefinition=%s\n",
ltype.data(),lname.data(),g_currentDefinition?g_currentDefinition->name().data():"<none>")); ltype.data(),lname.data(),g_currentDefinition?g_currentDefinition->name().data():"<none>"));
Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast(); Scope *scope = m_scopes.count()==0 ? &m_globalScope : m_scopes.getLast();
ClassDef *varType; ClassDef *varType;
...@@ -232,7 +232,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name) ...@@ -232,7 +232,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name)
(varType=getResolvedClass(g_currentDefinition,g_sourceFileDef,ltype)) // look for global class definitions (varType=getResolvedClass(g_currentDefinition,g_sourceFileDef,ltype)) // look for global class definitions
) )
{ {
DBG_CTX((stderr,"** addVariable type=%s name=%s\n",ltype.data(),lname.data())); DBG_CTX((stderr,"** addVariable type='%s' name='%s'\n",ltype.data(),lname.data()));
scope->append(lname,varType); // add it to a list scope->append(lname,varType); // add it to a list
} }
else if ((i=ltype.find('<'))!=-1) else if ((i=ltype.find('<'))!=-1)
...@@ -253,7 +253,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name) ...@@ -253,7 +253,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name)
} }
if (newDef) if (newDef)
{ {
DBG_CTX((stderr,"** addVariable type=%s templ=%s name=%s\n",typeName.data(),templateArgs.data(),lname.data())); DBG_CTX((stderr,"** addVariable type='%s' templ='%s' name='%s'\n",typeName.data(),templateArgs.data(),lname.data()));
scope->append(lname, newDef); scope->append(lname, newDef);
} }
else else
...@@ -268,7 +268,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name) ...@@ -268,7 +268,7 @@ void VariableContext::addVariable(const QCString &type,const QCString &name)
// is hidden to avoid false links to global variables with the same name // is hidden to avoid false links to global variables with the same name
// TODO: make this work for namespaces as well! // TODO: make this work for namespaces as well!
{ {
DBG_CTX((stderr,"** addVariable: dummy context\n")); DBG_CTX((stderr,"** addVariable: dummy context for '%s'\n",lname.data()));
scope->append(lname,dummyContext); scope->append(lname,dummyContext);
} }
else else
...@@ -876,7 +876,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, ...@@ -876,7 +876,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName,
} }
QCString className=clName; QCString className=clName;
if (className.isEmpty()) return; if (className.isEmpty()) return;
if (g_insideProtocolList) if (g_insideProtocolList) // for Obj-C
{ {
className+="-p"; className+="-p";
} }
...@@ -919,10 +919,14 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName, ...@@ -919,10 +919,14 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,char *clName,
{ {
//printf("non-dummy context lcd=%s!\n",lcd->name().data()); //printf("non-dummy context lcd=%s!\n",lcd->name().data());
g_theCallContext.setClass(lcd); g_theCallContext.setClass(lcd);
if (getLink(g_classScope,clName,ol,clName))
{ // to following is needed for links to a global variable, but is
return; // no good for a link to a local variable that is also a global symbol.
}
//if (getLink(g_classScope,clName,ol,clName))
//{
//return;
//}
} }
isLocal=TRUE; isLocal=TRUE;
//fprintf(stderr,"is a local variable cd=%p!\n",cd); //fprintf(stderr,"is a local variable cd=%p!\n",cd);
...@@ -1750,6 +1754,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -1750,6 +1754,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
if (!g_curClassName.isEmpty()) // valid class name if (!g_curClassName.isEmpty()) // valid class name
{ {
pushScope(g_curClassName); pushScope(g_curClassName);
DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
g_scopeStack.push(SCOPEBLOCK); g_scopeStack.push(SCOPEBLOCK);
} }
} }
...@@ -1859,6 +1864,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -1859,6 +1864,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
<Body,FuncCall>"{" { <Body,FuncCall>"{" {
g_theVarContext.pushScope(); g_theVarContext.pushScope();
DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
g_scopeStack.push(INNERBLOCK); g_scopeStack.push(INNERBLOCK);
if (g_searchingForBody) if (g_searchingForBody)
...@@ -1874,11 +1880,15 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -1874,11 +1880,15 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
} }
g_type.resize(0); g_type.resize(0);
g_name.resize(0); g_name.resize(0);
BEGIN( Body );
} }
<Body,MemberCall,MemberCall2>"}" { <Body,MemberCall,MemberCall2>"}" {
g_theVarContext.popScope(); g_theVarContext.popScope();
g_type.resize(0);
g_name.resize(0);
int *scope = g_scopeStack.pop(); int *scope = g_scopeStack.pop();
DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK));
if (scope==SCOPEBLOCK || scope==CLASSBLOCK) if (scope==SCOPEBLOCK || scope==CLASSBLOCK)
{ {
popScope(); popScope();
...@@ -1914,6 +1924,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -1914,6 +1924,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
g_theVarContext.popScope(); g_theVarContext.popScope();
int *scope = g_scopeStack.pop(); int *scope = g_scopeStack.pop();
DBG_CTX((stderr,"** scope stack pop SCOPEBLOCK=%d\n",scope==SCOPEBLOCK));
if (scope==SCOPEBLOCK || scope==CLASSBLOCK) if (scope==SCOPEBLOCK || scope==CLASSBLOCK)
{ {
popScope(); popScope();
...@@ -1980,7 +1991,10 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -1980,7 +1991,10 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
<ClassVar>{ID} { <ClassVar>{ID} {
g_type = g_curClassName.copy(); g_type = g_curClassName.copy();
g_name = yytext; g_name = yytext;
g_theVarContext.addVariable(g_type,g_name); if (g_insideBody)
{
g_theVarContext.addVariable(g_type,g_name);
}
generateClassOrGlobalLink(*g_code,yytext); generateClassOrGlobalLink(*g_code,yytext);
} }
<ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*":"{B}* { <ClassName,ClassVar,CppCliTypeModifierFollowup>{B}*":"{B}* {
...@@ -2005,6 +2019,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -2005,6 +2019,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
if (g_insideBody) g_bodyCurlyCount++; if (g_insideBody) g_bodyCurlyCount++;
if (!g_curClassName.isEmpty()) // valid class name if (!g_curClassName.isEmpty()) // valid class name
{ {
DBG_CTX((stderr,"** scope stack push CLASSBLOCK\n"));
g_scopeStack.push(CLASSBLOCK); g_scopeStack.push(CLASSBLOCK);
pushScope(g_curClassName); pushScope(g_curClassName);
//fprintf(stderr,"***** g_curClassName=%s\n",g_curClassName.data()); //fprintf(stderr,"***** g_curClassName=%s\n",g_curClassName.data());
...@@ -2032,6 +2047,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -2032,6 +2047,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
} }
else // not a class name -> assume inner block else // not a class name -> assume inner block
{ {
DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
g_scopeStack.push(INNERBLOCK); g_scopeStack.push(INNERBLOCK);
} }
g_curClassName.resize(0); g_curClassName.resize(0);
...@@ -2185,6 +2201,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -2185,6 +2201,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
if (*yytext==')') if (*yytext==')')
{ {
g_theCallContext.popScope(); g_theCallContext.popScope();
g_bracketCount--;
BEGIN(FuncCall); BEGIN(FuncCall);
} }
} }
...@@ -2440,6 +2457,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -2440,6 +2457,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
g_saveType = g_type.copy(); g_saveType = g_type.copy();
if (*yytext!='[' && !g_type.isEmpty()) if (*yytext!='[' && !g_type.isEmpty())
{ {
//printf("g_scopeStack.bottom()=%p\n",g_scopeStack.bottom());
if (g_scopeStack.top()!=CLASSBLOCK) if (g_scopeStack.top()!=CLASSBLOCK)
{ {
//printf("AddVariable: '%s' '%s' context=%d\n", //printf("AddVariable: '%s' '%s' context=%d\n",
...@@ -2625,6 +2643,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -2625,6 +2643,7 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
g_parmType.resize(0);g_parmName.resize(0); g_parmType.resize(0);g_parmName.resize(0);
} }
<MemberCall2,FuncCall>"(" { <MemberCall2,FuncCall>"(" {
g_parmType.resize(0);g_parmName.resize(0);
g_code->codify(yytext); g_code->codify(yytext);
g_bracketCount++; g_bracketCount++;
g_theCallContext.pushScope(); g_theCallContext.pushScope();
...@@ -2717,10 +2736,12 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -2717,10 +2736,12 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
{ {
setClassScope(g_realScope); setClassScope(g_realScope);
} }
DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
g_scopeStack.push(SCOPEBLOCK); g_scopeStack.push(SCOPEBLOCK);
} }
else else
{ {
DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
g_scopeStack.push(INNERBLOCK); g_scopeStack.push(INNERBLOCK);
} }
yytext[yyleng-1]='\0'; yytext[yyleng-1]='\0';
...@@ -2806,11 +2827,13 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP} ...@@ -2806,11 +2827,13 @@ OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
if (g_insideBody) g_bodyCurlyCount++; if (g_insideBody) g_bodyCurlyCount++;
if (g_name.find("::")!=-1) if (g_name.find("::")!=-1)
{ {
DBG_CTX((stderr,"** scope stack push SCOPEBLOCK\n"));
g_scopeStack.push(SCOPEBLOCK); g_scopeStack.push(SCOPEBLOCK);
setClassScope(g_realScope); setClassScope(g_realScope);
} }
else else
{ {
DBG_CTX((stderr,"** scope stack push INNERBLOCK\n"));
g_scopeStack.push(INNERBLOCK); g_scopeStack.push(INNERBLOCK);
} }
g_type.resize(0); g_name.resize(0); g_type.resize(0); g_name.resize(0);
......
...@@ -272,7 +272,7 @@ class DocCmdMapper ...@@ -272,7 +272,7 @@ class DocCmdMapper
{ {
if (m_map.find(p->cmdName)!=0) if (m_map.find(p->cmdName)!=0)
{ {
printf("Error: command %s already added\n",p->cmdName); printf("Error: DocCmdMapper: command %s already added\n",p->cmdName);
exit(1); exit(1);
} }
Cmd *cmd = new Cmd; Cmd *cmd = new Cmd;
...@@ -687,7 +687,14 @@ static inline void setOutput(OutputContext ctx) ...@@ -687,7 +687,14 @@ static inline void setOutput(OutputContext ctx)
current->briefLine = yyLineNr; current->briefLine = yyLineNr;
} }
} }
pOutputString = &current->brief; if (current->brief.isEmpty())
{
pOutputString = &current->brief;
}
else
{
pOutputString = &current->doc;
}
break; break;
case OutputXRef: case OutputXRef:
pOutputString = &outputXRef; pOutputString = &outputXRef;
......
...@@ -647,6 +647,8 @@ static void readIncludeFile(const char *incName) ...@@ -647,6 +647,8 @@ static void readIncludeFile(const char *incName)
tmpString.resize(0); tmpString.resize(0);
} }
<GetQuotedString>"\""|"\n" { <GetQuotedString>"\""|"\n" {
// we add a bogus space to signal that the string was quoted. This space will be stripped later on.
tmpString+=" ";
//printf("Quoted String = `%s'\n",tmpString.data()); //printf("Quoted String = `%s'\n",tmpString.data());
if (lastState==GetString) if (lastState==GetString)
{ {
...@@ -790,6 +792,8 @@ static void substEnvVarsInString(QCString &s) ...@@ -790,6 +792,8 @@ static void substEnvVarsInString(QCString &s)
s = s.left(i)+env+s.right(s.length()-i-l); s = s.left(i)+env+s.right(s.length()-i-l);
p=i+env.length(); // next time start at the end of the expanded string p=i+env.length(); // next time start at the end of the expanded string
} }
s=s.stripWhiteSpace(); // to strip the bogus space that was added when an argument
// has quotes
//printf("substEnvVarInString(%s) end\n",s.data()); //printf("substEnvVarInString(%s) end\n",s.data());
} }
...@@ -799,7 +803,9 @@ static void substEnvVarsInStrList(QStrList &sl) ...@@ -799,7 +803,9 @@ static void substEnvVarsInStrList(QStrList &sl)
while (s) while (s)
{ {
QCString result(s); QCString result(s);
// an argument with quotes will have an extra space at the end, so wasQuoted will be TRUE.
bool wasQuoted = (result.find(' ')!=-1) || (result.find('\t')!=-1); bool wasQuoted = (result.find(' ')!=-1) || (result.find('\t')!=-1);
// here we strip the quote again
substEnvVarsInString(result); substEnvVarsInString(result);
//printf("Result %s was quoted=%d\n",result.data(),wasQuoted); //printf("Result %s was quoted=%d\n",result.data(),wasQuoted);
...@@ -1717,6 +1723,14 @@ void Config::create() ...@@ -1717,6 +1723,14 @@ void Config::create()
"If set to NO (the default) only methods in the interface are included. \n", "If set to NO (the default) only methods in the interface are included. \n",
FALSE FALSE
); );
cb = addBool(
"EXTRACT_ANON_NSPACES",
"If this flag is set to YES, the members of anonymous namespaces will be extracted \n"
"and appear in the documentation as a namespace called 'anonymous_namespace{file}', \n"
"where file will be replaced with the base name of the file that contains the anonymous \n"
"namespace. By default anonymous namespace are hidden. \n",
FALSE
);
cb = addBool( cb = addBool(
"HIDE_UNDOC_MEMBERS", "HIDE_UNDOC_MEMBERS",
"If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \n" "If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \n"
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "qtbc.h" #include "qtbc.h"
#include <ctype.h> #include <ctype.h>
#include <qregexp.h> #include <qregexp.h>
#include <md5.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
...@@ -63,6 +64,7 @@ class DefinitionImpl ...@@ -63,6 +64,7 @@ class DefinitionImpl
DocInfo *details; // not exported DocInfo *details; // not exported
BriefInfo *brief; // not exported BriefInfo *brief; // not exported
BodyInfo *body; // not exported BodyInfo *body; // not exported
QCString docSignatures;
QCString localName; // local (unqualified) name of the definition QCString localName; // local (unqualified) name of the definition
// in the future m_name should become m_localName // in the future m_name should become m_localName
...@@ -280,7 +282,7 @@ Definition::Definition(const char *df,int dl, ...@@ -280,7 +282,7 @@ Definition::Definition(const char *df,int dl,
m_isSymbol = isSymbol; m_isSymbol = isSymbol;
if (isSymbol) addToMap(name,this); if (isSymbol) addToMap(name,this);
_setBriefDescription(b,df,dl); _setBriefDescription(b,df,dl);
_setDocumentation(d,df,dl,TRUE); _setDocumentation(d,df,dl,TRUE,FALSE);
if (matchExcludedSymbols(name)) m_impl->hidden = TRUE; if (matchExcludedSymbols(name)) m_impl->hidden = TRUE;
} }
...@@ -348,7 +350,25 @@ void Definition::writeDocAnchorsToTagFile() ...@@ -348,7 +350,25 @@ void Definition::writeDocAnchorsToTagFile()
} }
} }
void Definition::_setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) bool Definition::_docsAlreadyAdded(const QString &doc)
{
uchar md5_sig[16];
QCString sigStr(33);
MD5Buffer((const unsigned char *)doc.data(),doc.length(),md5_sig);
MD5SigToString(md5_sig,sigStr.data(),33);
if (m_impl->docSignatures.find(sigStr)==-1) // new docs, add signature to prevent re-adding it
{
m_impl->docSignatures+=":"+sigStr;
return FALSE;
}
else
{
return TRUE;
}
}
void Definition::_setDocumentation(const char *d,const char *docFile,int docLine,
bool stripWhiteSpace,bool atTop)
{ {
if (d==0) return; if (d==0) return;
//printf("Definition::setDocumentation(%s,%s,%d,%d)\n",d,docFile,docLine,stripWhiteSpace); //printf("Definition::setDocumentation(%s,%s,%d,%d)\n",d,docFile,docLine,stripWhiteSpace);
...@@ -361,52 +381,82 @@ void Definition::_setDocumentation(const char *d,const char *docFile,int docLine ...@@ -361,52 +381,82 @@ void Definition::_setDocumentation(const char *d,const char *docFile,int docLine
{ {
doc=d; doc=d;
} }
//printf("setting docs for %s: `%s'\n",name().data(),m_doc.data()); if (!_docsAlreadyAdded(doc))
if (m_impl->details==0)
{ {
m_impl->details = new DocInfo; //printf("setting docs for %s: `%s'\n",name().data(),m_doc.data());
if (m_impl->details==0)
{
m_impl->details = new DocInfo;
}
if (m_impl->details->doc.isEmpty()) // fresh detailed description
{
m_impl->details->doc = doc;
}
else if (atTop) // another detailed description, append it to the start
{
m_impl->details->doc = doc+"\n\n"+m_impl->details->doc;
}
else // another detailed description, append it to the end
{
m_impl->details->doc += "\n\n"+doc;
}
if (docLine!=-1) // store location if valid
{
m_impl->details->file = docFile;
m_impl->details->line = docLine;
}
} }
m_impl->details->doc = doc;
m_impl->details->file = docFile;
m_impl->details->line = docLine;
} }
void Definition::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace) void Definition::setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace)
{ {
if (d==0) return; if (d==0) return;
makeResident(); makeResident();
_setDocumentation(d,docFile,docLine,stripWhiteSpace); _setDocumentation(d,docFile,docLine,stripWhiteSpace,FALSE);
} }
#define uni_isupper(c) (QChar(c).category()==QChar::Letter_Uppercase) #define uni_isupper(c) (QChar(c).category()==QChar::Letter_Uppercase)
void Definition::_setBriefDescription(const char *b,const char *briefFile,int briefLine) void Definition::_setBriefDescription(const char *b,const char *briefFile,int briefLine)
{ {
if (b==0) return;
static QCString outputLanguage = Config_getEnum("OUTPUT_LANGUAGE"); static QCString outputLanguage = Config_getEnum("OUTPUT_LANGUAGE");
static bool needsDot = outputLanguage!="Japanese" && static bool needsDot = outputLanguage!="Japanese" &&
outputLanguage!="Chinese" && outputLanguage!="Chinese" &&
outputLanguage!="Korean"; outputLanguage!="Korean";
//fprintf(stderr,"Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine); QCString brief = b;
if (m_impl->brief==0) brief = brief.stripWhiteSpace();
{ if (brief.isEmpty()) return;
m_impl->brief = new BriefInfo; int bl = brief.length();
}
m_impl->brief->doc=QCString(b).stripWhiteSpace();
int bl=m_impl->brief->doc.length();
if (bl>0 && needsDot) // add punctuation if needed if (bl>0 && needsDot) // add punctuation if needed
{ {
switch(m_impl->brief->doc.at(bl-1)) switch(brief.at(bl-1))
{ {
case '.': case '!': case '?': break; case '.': case '!': case '?': break;
default: default:
if (uni_isupper(m_impl->brief->doc.at(0))) m_impl->brief->doc+='.'; if (uni_isupper(brief.at(0))) brief+='.';
break; break;
} }
} }
m_impl->brief->file = briefFile;
m_impl->brief->line = briefLine; if (m_impl->brief && !m_impl->brief->doc.isEmpty())
m_impl->brief->tooltip = parseCommentAsText(m_impl->brief->doc,briefFile,briefLine); {
//printf("adding to details\n");
_setDocumentation(brief,briefFile,briefLine,FALSE,TRUE);
}
else if (!_docsAlreadyAdded(brief))
{
//fprintf(stderr,"Definition::setBriefDescription(%s,%s,%d)\n",b,briefFile,briefLine);
if (m_impl->brief==0)
{
m_impl->brief = new BriefInfo;
}
m_impl->brief->doc=brief;
if (briefLine!=-1)
{
m_impl->brief->file = briefFile;
m_impl->brief->line = briefLine;
}
}
} }
void Definition::setBriefDescription(const char *b,const char *briefFile,int briefLine) void Definition::setBriefDescription(const char *b,const char *briefFile,int briefLine)
...@@ -1100,7 +1150,24 @@ QCString Definition::briefDescription() const ...@@ -1100,7 +1150,24 @@ QCString Definition::briefDescription() const
QCString Definition::briefDescriptionAsTooltip() const QCString Definition::briefDescriptionAsTooltip() const
{ {
makeResident(); makeResident();
return m_impl->brief ? m_impl->brief->tooltip : QCString(""); if (m_impl->brief)
{
if (m_impl->brief->tooltip.isEmpty() && !m_impl->brief->doc.isEmpty())
{
static bool reentering=FALSE;
if (!reentering)
{
reentering=TRUE; // prevent requests for tooltips while parsing a tooltip
m_impl->brief->tooltip = parseCommentAsText(
m_impl->brief->doc,
m_impl->brief->file,
m_impl->brief->line);
reentering=FALSE;
}
}
return m_impl->brief->tooltip;
}
return QCString("");
} }
int Definition::briefLine() const int Definition::briefLine() const
...@@ -1245,6 +1312,7 @@ void Definition::flushToDisk() const ...@@ -1245,6 +1312,7 @@ void Definition::flushToDisk() const
marshalDocInfo (Doxygen::symbolStorage,m_impl->details); marshalDocInfo (Doxygen::symbolStorage,m_impl->details);
marshalBriefInfo (Doxygen::symbolStorage,m_impl->brief); marshalBriefInfo (Doxygen::symbolStorage,m_impl->brief);
marshalBodyInfo (Doxygen::symbolStorage,m_impl->body); marshalBodyInfo (Doxygen::symbolStorage,m_impl->body);
marshalQCString (Doxygen::symbolStorage,m_impl->docSignatures);
marshalQCString (Doxygen::symbolStorage,m_impl->localName); marshalQCString (Doxygen::symbolStorage,m_impl->localName);
marshalQCString (Doxygen::symbolStorage,m_impl->qualifiedName); marshalQCString (Doxygen::symbolStorage,m_impl->qualifiedName);
marshalQCString (Doxygen::symbolStorage,m_impl->ref); marshalQCString (Doxygen::symbolStorage,m_impl->ref);
...@@ -1274,6 +1342,7 @@ void Definition::loadFromDisk() const ...@@ -1274,6 +1342,7 @@ void Definition::loadFromDisk() const
m_impl->details = unmarshalDocInfo (Doxygen::symbolStorage); m_impl->details = unmarshalDocInfo (Doxygen::symbolStorage);
m_impl->brief = unmarshalBriefInfo (Doxygen::symbolStorage); m_impl->brief = unmarshalBriefInfo (Doxygen::symbolStorage);
m_impl->body = unmarshalBodyInfo (Doxygen::symbolStorage); m_impl->body = unmarshalBodyInfo (Doxygen::symbolStorage);
m_impl->docSignatures = unmarshalQCString (Doxygen::symbolStorage);
m_impl->localName = unmarshalQCString (Doxygen::symbolStorage); m_impl->localName = unmarshalQCString (Doxygen::symbolStorage);
m_impl->qualifiedName = unmarshalQCString (Doxygen::symbolStorage); m_impl->qualifiedName = unmarshalQCString (Doxygen::symbolStorage);
m_impl->ref = unmarshalQCString (Doxygen::symbolStorage); m_impl->ref = unmarshalQCString (Doxygen::symbolStorage);
......
...@@ -310,7 +310,8 @@ class Definition : public DefinitionIntf, public LockableObj ...@@ -310,7 +310,8 @@ class Definition : public DefinitionIntf, public LockableObj
void _writeSourceRefList(OutputList &ol,const char *scopeName, void _writeSourceRefList(OutputList &ol,const char *scopeName,
const QCString &text,MemberSDict *members,bool); const QCString &text,MemberSDict *members,bool);
void _setBriefDescription(const char *b,const char *briefFile,int briefLine); void _setBriefDescription(const char *b,const char *briefFile,int briefLine);
void _setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace); void _setDocumentation(const char *d,const char *docFile,int docLine,bool stripWhiteSpace,bool atTop);
bool _docsAlreadyAdded(const QString &doc);
DefinitionImpl *m_impl; // internal structure holding all private data DefinitionImpl *m_impl; // internal structure holding all private data
QCString m_name; QCString m_name;
bool m_isSymbol; bool m_isSymbol;
......
...@@ -68,23 +68,7 @@ static const char *sectionLevelToName[] = ...@@ -68,23 +68,7 @@ static const char *sectionLevelToName[] =
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// global variables during a call to validatingParseDoc // Parser state: global variables during a call to validatingParseDoc
static bool g_hasParamCommand;
static bool g_hasReturnCommand;
static MemberDef * g_memberDef;
static QDict<void> g_paramsFound;
static bool g_isExample;
static QCString g_exampleName;
static SectionDict *g_sectionDict;
static QCString g_searchUrl;
// include file state
static QString g_includeFileText;
static uint g_includeFileOffset;
static uint g_includeFileLength;
// parser state
static QString g_context; static QString g_context;
static bool g_inSeeBlock; static bool g_inSeeBlock;
static bool g_insideHtmlLink; static bool g_insideHtmlLink;
...@@ -95,6 +79,20 @@ static QList<Definition> g_copyStack; ...@@ -95,6 +79,20 @@ static QList<Definition> g_copyStack;
static QString g_fileName; static QString g_fileName;
static QString g_relPath; static QString g_relPath;
static bool g_hasParamCommand;
static bool g_hasReturnCommand;
static MemberDef * g_memberDef;
static QDict<void> g_paramsFound;
static bool g_isExample;
static QCString g_exampleName;
static SectionDict * g_sectionDict;
static QCString g_searchUrl;
static QString g_includeFileText;
static uint g_includeFileOffset;
static uint g_includeFileLength;
// parser's context to store all global variables
struct DocParserContext struct DocParserContext
{ {
QString context; QString context;
...@@ -104,9 +102,23 @@ struct DocParserContext ...@@ -104,9 +102,23 @@ struct DocParserContext
QStack<DocStyleChange> styleStack; QStack<DocStyleChange> styleStack;
QStack<DocStyleChange> initialStyleStack; QStack<DocStyleChange> initialStyleStack;
QList<Definition> copyStack; QList<Definition> copyStack;
MemberDef *memberDef;
QString fileName; QString fileName;
QString relPath; QString relPath;
bool hasParamCommand;
bool hasReturnCommand;
MemberDef * memberDef;
QDict<void> paramsFound;
bool isExample;
QCString exampleName;
SectionDict *sectionDict;
QCString searchUrl;
QString includeFileText;
uint includeFileOffset;
uint includeFileLength;
TokenInfo *token;
}; };
static QStack<DocParserContext> g_parserStack; static QStack<DocParserContext> g_parserStack;
...@@ -115,6 +127,10 @@ static QStack<DocParserContext> g_parserStack; ...@@ -115,6 +127,10 @@ static QStack<DocParserContext> g_parserStack;
static void docParserPushContext() static void docParserPushContext()
{ {
//QCString indent;
//indent.fill(' ',g_parserStack.count()*2+2);
//printf("%sdocParserPushContext() count=%d\n",indent.data(),g_nodeStack.count());
doctokenizerYYpushContext(); doctokenizerYYpushContext();
DocParserContext *ctx = new DocParserContext; DocParserContext *ctx = new DocParserContext;
ctx->context = g_context; ctx->context = g_context;
...@@ -126,6 +142,23 @@ static void docParserPushContext() ...@@ -126,6 +142,23 @@ static void docParserPushContext()
ctx->copyStack = g_copyStack; ctx->copyStack = g_copyStack;
ctx->fileName = g_fileName; ctx->fileName = g_fileName;
ctx->relPath = g_relPath; ctx->relPath = g_relPath;
ctx->hasParamCommand = g_hasParamCommand;
ctx->hasReturnCommand = g_hasReturnCommand;
ctx->memberDef = g_memberDef;
ctx->paramsFound = g_paramsFound;
ctx->isExample = g_isExample;
ctx->exampleName = g_exampleName;
ctx->sectionDict = g_sectionDict;
ctx->searchUrl = g_searchUrl;
ctx->includeFileText = g_includeFileText;
ctx->includeFileOffset = g_includeFileOffset;
ctx->includeFileLength = g_includeFileLength;
ctx->token = g_token;
g_token = new TokenInfo;
g_parserStack.push(ctx); g_parserStack.push(ctx);
} }
...@@ -141,8 +174,29 @@ static void docParserPopContext() ...@@ -141,8 +174,29 @@ static void docParserPopContext()
g_copyStack = ctx->copyStack; g_copyStack = ctx->copyStack;
g_fileName = ctx->fileName; g_fileName = ctx->fileName;
g_relPath = ctx->relPath; g_relPath = ctx->relPath;
g_hasParamCommand = ctx->hasParamCommand;
g_hasReturnCommand = ctx->hasReturnCommand;
g_memberDef = ctx->memberDef;
g_paramsFound = ctx->paramsFound;
g_isExample = ctx->isExample;
g_exampleName = ctx->exampleName;
g_sectionDict = ctx->sectionDict;
g_searchUrl = ctx->searchUrl;
g_includeFileText = ctx->includeFileText;
g_includeFileOffset = ctx->includeFileOffset;
g_includeFileLength = ctx->includeFileLength;
delete g_token;
g_token = ctx->token;
delete ctx; delete ctx;
doctokenizerYYpopContext(); doctokenizerYYpopContext();
//QCString indent;
//indent.fill(' ',g_parserStack.count()*2+2);
//printf("%sdocParserPopContext() count=%d\n",indent.data(),g_nodeStack.count());
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
...@@ -5876,7 +5930,10 @@ DocNode *validatingParseDoc(const char *fileName,int startLine, ...@@ -5876,7 +5930,10 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
// md?md->name().data():"<none>"); // md?md->name().data():"<none>");
//printf("========== validating %s at line %d\n",fileName,startLine); //printf("========== validating %s at line %d\n",fileName,startLine);
//printf("---------------- input --------------------\n%s\n----------- end input -------------------\n",input); //printf("---------------- input --------------------\n%s\n----------- end input -------------------\n",input);
g_token = new TokenInfo; //g_token = new TokenInfo;
// store parser state so we can re-enter this function if needed
docParserPushContext();
if (ctx && if (ctx &&
(ctx->definitionType()==Definition::TypeClass || (ctx->definitionType()==Definition::TypeClass ||
...@@ -5999,10 +6056,12 @@ DocNode *validatingParseDoc(const char *fileName,int startLine, ...@@ -5999,10 +6056,12 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
doctokenizerYYlineno=startLine; doctokenizerYYlineno=startLine;
doctokenizerYYinit(input,g_fileName); doctokenizerYYinit(input,g_fileName);
// build abstract syntax tree // build abstract syntax tree
DocRoot *root = new DocRoot(md!=0,singleLine); DocRoot *root = new DocRoot(md!=0,singleLine);
root->parse(); root->parse();
if (Debug::isFlagSet(Debug::PrintTree)) if (Debug::isFlagSet(Debug::PrintTree))
{ {
// pretty print the result // pretty print the result
...@@ -6011,24 +6070,29 @@ DocNode *validatingParseDoc(const char *fileName,int startLine, ...@@ -6011,24 +6070,29 @@ DocNode *validatingParseDoc(const char *fileName,int startLine,
delete v; delete v;
} }
checkUndocumentedParams(); checkUndocumentedParams();
detectNoDocumentedParams(); detectNoDocumentedParams();
delete g_token;
// TODO: These should be called at the end of the program. // TODO: These should be called at the end of the program.
//doctokenizerYYcleanup(); //doctokenizerYYcleanup();
//Mappers::cmdMapper->freeInstance(); //Mappers::cmdMapper->freeInstance();
//Mappers::htmlTagMapper->freeInstance(); //Mappers::htmlTagMapper->freeInstance();
// restore original parser state
docParserPopContext();
return root; return root;
} }
DocNode *validatingParseText(const char *input) DocNode *validatingParseText(const char *input)
{ {
// store parser state so we can re-enter this function if needed
docParserPushContext();
//printf("------------ input ---------\n%s\n" //printf("------------ input ---------\n%s\n"
// "------------ end input -----\n",input); // "------------ end input -----\n",input);
g_token = new TokenInfo; //g_token = new TokenInfo;
g_context = ""; g_context = "";
g_fileName = "<parseText>"; g_fileName = "<parseText>";
g_relPath = ""; g_relPath = "";
...@@ -6068,8 +6132,8 @@ DocNode *validatingParseText(const char *input) ...@@ -6068,8 +6132,8 @@ DocNode *validatingParseText(const char *input)
} }
} }
delete g_token; // restore original parser state
docParserPopContext();
return txt; return txt;
} }
......
...@@ -488,6 +488,7 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional) ...@@ -488,6 +488,7 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional)
if ((gd=Doxygen::groupSDict->find(root->name))) if ((gd=Doxygen::groupSDict->find(root->name)))
{ {
#if 0
if ( root->groupDocType==Entry::GROUPDOC_NORMAL ) if ( root->groupDocType==Entry::GROUPDOC_NORMAL )
{ {
warn(root->fileName,root->startLine, warn(root->fileName,root->startLine,
...@@ -496,6 +497,7 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional) ...@@ -496,6 +497,7 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional)
root->name.data()); root->name.data());
} }
else else
#endif
{ {
if ( !gd->hasGroupTitle() ) if ( !gd->hasGroupTitle() )
gd->setGroupTitle( root->type ); gd->setGroupTitle( root->type );
...@@ -503,12 +505,10 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional) ...@@ -503,12 +505,10 @@ static void buildGroupListFiltered(EntryNav *rootNav,bool additional)
warn( root->fileName,root->startLine, warn( root->fileName,root->startLine,
"group %s: ignoring title \"%s\" that does not match old title \"%s\"\n", "group %s: ignoring title \"%s\" that does not match old title \"%s\"\n",
root->name.data(), root->type.data(), gd->groupTitle() ); root->name.data(), root->type.data(), gd->groupTitle() );
if ( gd->briefDescription().isEmpty() ) //if ( gd->briefDescription().isEmpty() )
gd->setBriefDescription(root->brief,root->briefFile,root->briefLine); gd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
if ( !root->doc.stripWhiteSpace().isEmpty() ) //if ( !root->doc.stripWhiteSpace().isEmpty() )
gd->setDocumentation( gd->documentation().isEmpty() ? root->doc : gd->setDocumentation( root->doc, root->docFile, root->docLine );
gd->documentation() + "\n\n" + root->doc,
root->docFile, root->docLine );
gd->addSectionsToDefinition(root->anchors); gd->addSectionsToDefinition(root->anchors);
gd->setRefItems(root->sli); gd->setRefItems(root->sli);
//addGroupToGroups(root,gd); //addGroupToGroups(root,gd);
...@@ -637,6 +637,7 @@ static void buildFileList(EntryNav *rootNav) ...@@ -637,6 +637,7 @@ static void buildFileList(EntryNav *rootNav)
//printf("**************** root->name=%s fd=%p\n",root->name.data(),fd); //printf("**************** root->name=%s fd=%p\n",root->name.data(),fd);
if (fd && !ambig) if (fd && !ambig)
{ {
#if 0
if ((!root->doc.isEmpty() && !fd->documentation().isEmpty()) || if ((!root->doc.isEmpty() && !fd->documentation().isEmpty()) ||
(!root->brief.isEmpty() && !fd->briefDescription().isEmpty())) (!root->brief.isEmpty() && !fd->briefDescription().isEmpty()))
{ {
...@@ -648,6 +649,7 @@ static void buildFileList(EntryNav *rootNav) ...@@ -648,6 +649,7 @@ static void buildFileList(EntryNav *rootNav)
); );
} }
else else
#endif
{ {
//printf("Adding documentation!\n"); //printf("Adding documentation!\n");
// using FALSE in setDocumentation is small hack to make sure a file // using FALSE in setDocumentation is small hack to make sure a file
...@@ -1088,6 +1090,7 @@ static void addClassToContext(EntryNav *rootNav) ...@@ -1088,6 +1090,7 @@ static void addClassToContext(EntryNav *rootNav)
// //printf("existing ClassDef tempArgList=%p specScope=%s\n",root->tArgList,root->scopeSpec.data()); // //printf("existing ClassDef tempArgList=%p specScope=%s\n",root->tArgList,root->scopeSpec.data());
// cd->setTemplateArguments(tArgList); // cd->setTemplateArguments(tArgList);
//} //}
#if 0
if (!root->doc.isEmpty() || !root->brief.isEmpty() || if (!root->doc.isEmpty() || !root->brief.isEmpty() ||
(root->bodyLine!=-1 && Config_getBool("SOURCE_BROWSER")) (root->bodyLine!=-1 && Config_getBool("SOURCE_BROWSER"))
) )
...@@ -1103,9 +1106,11 @@ static void addClassToContext(EntryNav *rootNav) ...@@ -1103,9 +1106,11 @@ static void addClassToContext(EntryNav *rootNav)
); );
} }
else if (!root->doc.isEmpty()) else if (!root->doc.isEmpty())
#endif
{ {
cd->setDocumentation(root->doc,root->docFile,root->docLine); cd->setDocumentation(root->doc,root->docFile,root->docLine);
} }
#if 0
if (!root->brief.isEmpty() && !cd->briefDescription().isEmpty()) if (!root->brief.isEmpty() && !cd->briefDescription().isEmpty())
{ {
warn( warn(
...@@ -1116,6 +1121,7 @@ static void addClassToContext(EntryNav *rootNav) ...@@ -1116,6 +1121,7 @@ static void addClassToContext(EntryNav *rootNav)
); );
} }
else if (!root->brief.isEmpty()) else if (!root->brief.isEmpty())
#endif
{ {
cd->setBriefDescription(root->brief,root->briefFile,root->briefLine); cd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
} }
...@@ -1125,7 +1131,9 @@ static void addClassToContext(EntryNav *rootNav) ...@@ -1125,7 +1131,9 @@ static void addClassToContext(EntryNav *rootNav)
cd->setBodyDef(fd); cd->setBodyDef(fd);
} }
//cd->setName(fullName); // change name to match docs //cd->setName(fullName); // change name to match docs
#if 0
} }
#endif
if (cd->templateArguments()==0) if (cd->templateArguments()==0)
{ {
...@@ -1360,13 +1368,13 @@ static void buildNamespaceList(EntryNav *rootNav) ...@@ -1360,13 +1368,13 @@ static void buildNamespaceList(EntryNav *rootNav)
//printf("** buildNamespaceList(%s)\n",root->name.data()); //printf("** buildNamespaceList(%s)\n",root->name.data());
QCString fullName = root->name; QCString fName = root->name;
if (root->section==Entry::PACKAGEDOC_SEC) if (root->section==Entry::PACKAGEDOC_SEC)
{ {
fullName=substitute(fullName,".","::"); fName=substitute(fName,".","::");
} }
fullName = stripAnonymousNamespaceScope(fullName); QCString fullName = stripAnonymousNamespaceScope(fName);
if (!fullName.isEmpty()) if (!fullName.isEmpty())
{ {
//printf("Found namespace %s in %s at line %d\n",root->name.data(), //printf("Found namespace %s in %s at line %d\n",root->name.data(),
...@@ -1374,13 +1382,16 @@ static void buildNamespaceList(EntryNav *rootNav) ...@@ -1374,13 +1382,16 @@ static void buildNamespaceList(EntryNav *rootNav)
NamespaceDef *nd; NamespaceDef *nd;
if ((nd=Doxygen::namespaceSDict->find(fullName))) // existing namespace if ((nd=Doxygen::namespaceSDict->find(fullName))) // existing namespace
{ {
#if 0
if (!root->doc.isEmpty() || !root->brief.isEmpty()) // block contains docs if (!root->doc.isEmpty() || !root->brief.isEmpty()) // block contains docs
{ {
if (nd->documentation().isEmpty() && !root->doc.isEmpty()) if (nd->documentation().isEmpty() && !root->doc.isEmpty())
{ {
#endif
nd->setDocumentation(root->doc,root->docFile,root->docLine); nd->setDocumentation(root->doc,root->docFile,root->docLine);
nd->setName(fullName); // change name to match docs nd->setName(fullName); // change name to match docs
nd->addSectionsToDefinition(root->anchors); nd->addSectionsToDefinition(root->anchors);
#if 0
} }
else if (!nd->documentation().isEmpty() && !root->doc.isEmpty()) else if (!nd->documentation().isEmpty() && !root->doc.isEmpty())
{ {
...@@ -1392,7 +1403,9 @@ static void buildNamespaceList(EntryNav *rootNav) ...@@ -1392,7 +1403,9 @@ static void buildNamespaceList(EntryNav *rootNav)
} }
if (nd->briefDescription().isEmpty() && !root->brief.isEmpty()) if (nd->briefDescription().isEmpty() && !root->brief.isEmpty())
{ {
#endif
nd->setBriefDescription(root->brief,root->briefFile,root->briefLine); nd->setBriefDescription(root->brief,root->briefFile,root->briefLine);
#if 0
nd->setName(fullName); // change name to match docs nd->setName(fullName); // change name to match docs
} }
else if (!nd->briefDescription().isEmpty() && !root->brief.isEmpty()) else if (!nd->briefDescription().isEmpty() && !root->brief.isEmpty())
...@@ -1404,6 +1417,7 @@ static void buildNamespaceList(EntryNav *rootNav) ...@@ -1404,6 +1417,7 @@ static void buildNamespaceList(EntryNav *rootNav)
); );
} }
} }
#endif
// file definition containing the namespace nd // file definition containing the namespace nd
FileDef *fd=rootNav->fileDef(); FileDef *fd=rootNav->fileDef();
...@@ -2199,7 +2213,8 @@ static int findFunctionPtr(const QCString &type,int *pLength=0) ...@@ -2199,7 +2213,8 @@ static int findFunctionPtr(const QCString &type,int *pLength=0)
if (!type.isEmpty() && // return type is non-empty if (!type.isEmpty() && // return type is non-empty
(i=re.match(type,0,&l))!=-1 && // contains (...*...) (i=re.match(type,0,&l))!=-1 && // contains (...*...)
type.find("operator")==-1 && // not an operator type.find("operator")==-1 && // not an operator
type.find(")(")==-1 // not a function pointer return type (type.find(")(")==-1 || type.find("typedef ")!=-1)
// not a function pointer return type
) )
{ {
if (pLength) *pLength=l; if (pLength) *pLength=l;
...@@ -2392,6 +2407,7 @@ static void buildVarList(EntryNav *rootNav) ...@@ -2392,6 +2407,7 @@ static void buildVarList(EntryNav *rootNav)
else else
{ {
int i=isFuncPtr; int i=isFuncPtr;
if (i==-1) i=findFunctionPtr(root->type); // for typedefs isFuncPtr is not yet set
if (i!=-1) // function pointer if (i!=-1) // function pointer
{ {
int ai = root->type.find('[',i); int ai = root->type.find('[',i);
...@@ -2847,10 +2863,16 @@ static void buildFunctionList(EntryNav *rootNav) ...@@ -2847,10 +2863,16 @@ static void buildFunctionList(EntryNav *rootNav)
{ {
NamespaceDef *mnd = md->getNamespaceDef(); NamespaceDef *mnd = md->getNamespaceDef();
NamespaceDef *rnd = 0; NamespaceDef *rnd = 0;
if (!rootNav->parent()->name().isEmpty()) //printf("root namespace=%s\n",rootNav->parent()->name().data());
QCString fullScope = scope;
QCString parentScope = rootNav->parent()->name();
if (!parentScope.isEmpty() && !leftScopeMatch(parentScope,scope))
{ {
rnd = getResolvedNamespace(rootNav->parent()->name()); if (!scope.isEmpty()) fullScope.prepend("::");
fullScope.prepend(parentScope);
} }
//printf("fullScope=%s\n",fullScope.data());
rnd = getResolvedNamespace(fullScope);
FileDef *mfd = md->getFileDef(); FileDef *mfd = md->getFileDef();
QCString nsName,rnsName; QCString nsName,rnsName;
if (mnd) nsName = mnd->name().copy(); if (mnd) nsName = mnd->name().copy();
...@@ -2870,6 +2892,7 @@ static void buildFunctionList(EntryNav *rootNav) ...@@ -2870,6 +2892,7 @@ static void buildFunctionList(EntryNav *rootNav)
gd = Doxygen::groupSDict->find(root->groups->first()->groupname.data()); gd = Doxygen::groupSDict->find(root->groups->first()->groupname.data());
} }
//printf("match!\n"); //printf("match!\n");
//printf("mnd=%p rnd=%p nsName=%s rnsName=%s\n",mnd,rnd,nsName.data(),rnsName.data());
// see if we need to create a new member // see if we need to create a new member
found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace found=(mnd && rnd && nsName==rnsName) || // members are in the same namespace
((mnd==0 && rnd==0 && mfd!=0 && // no external reference and ((mnd==0 && rnd==0 && mfd!=0 && // no external reference and
...@@ -2893,9 +2916,6 @@ static void buildFunctionList(EntryNav *rootNav) ...@@ -2893,9 +2916,6 @@ static void buildFunctionList(EntryNav *rootNav)
// merge documentation // merge documentation
if (md->documentation().isEmpty() && !root->doc.isEmpty()) if (md->documentation().isEmpty() && !root->doc.isEmpty())
{ {
md->setDocumentation(root->doc,root->docFile,root->docLine);
md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
md->setDocsForDefinition(!root->proto);
ArgumentList *argList = new ArgumentList; ArgumentList *argList = new ArgumentList;
stringToArgumentList(root->args,argList); stringToArgumentList(root->args,argList);
if (root->proto) if (root->proto)
...@@ -2908,21 +2928,28 @@ static void buildFunctionList(EntryNav *rootNav) ...@@ -2908,21 +2928,28 @@ static void buildFunctionList(EntryNav *rootNav)
md->setArgumentList(argList); md->setArgumentList(argList);
} }
} }
#if 0
else if (!md->documentation().isEmpty() && !root->doc.isEmpty() && mnd==rnd) else if (!md->documentation().isEmpty() && !root->doc.isEmpty() && mnd==rnd)
{ {
warn(root->docFile,root->docLine,"Warning: member %s: ignoring the detailed description found here, since another one was found at line %d of file %s!",md->name().data(),md->docLine(),md->docFile().data()); warn(root->docFile,root->docLine,"Warning: member %s: ignoring the detailed description found here, since another one was found at line %d of file %s!",md->name().data(),md->docLine(),md->docFile().data());
//printf("md->docs=[%s] root->docs=[%s]\n",md->documentation().data(),root->doc.data()); //printf("md->docs=[%s] root->docs=[%s]\n",md->documentation().data(),root->doc.data());
} }
#endif
md->setDocumentation(root->doc,root->docFile,root->docLine);
md->setInbodyDocumentation(root->inbodyDocs,root->inbodyFile,root->inbodyLine);
md->setDocsForDefinition(!root->proto);
if (md->briefDescription().isEmpty() && !root->brief.isEmpty()) if (md->briefDescription().isEmpty() && !root->brief.isEmpty())
{ {
md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
md->setArgsString(root->args); md->setArgsString(root->args);
} }
#if 0
else if (!md->briefDescription().isEmpty() && !root->brief.isEmpty() && mnd==rnd) else if (!md->briefDescription().isEmpty() && !root->brief.isEmpty() && mnd==rnd)
{ {
warn(root->briefFile,root->briefLine,"Warning: member %s: ignoring the brief description found here, since another one was found at line %d of file %s!",md->name().data(),md->briefLine(),md->briefFile().data()); warn(root->briefFile,root->briefLine,"Warning: member %s: ignoring the brief description found here, since another one was found at line %d of file %s!",md->name().data(),md->briefLine(),md->briefFile().data());
} }
#endif
md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
md->addSectionsToDefinition(root->anchors); md->addSectionsToDefinition(root->anchors);
...@@ -4648,6 +4675,8 @@ static void addMemberDocs(EntryNav *rootNav, ...@@ -4648,6 +4675,8 @@ static void addMemberDocs(EntryNav *rootNav,
//printf("Adding docs md->docs=`%s' root->docs=`%s'!\n", //printf("Adding docs md->docs=`%s' root->docs=`%s'!\n",
// md->documentation().data(),root->doc.data()); // md->documentation().data(),root->doc.data());
// documentation outside a compound overrides the documentation inside it // documentation outside a compound overrides the documentation inside it
#if 0
if ( /* !md->isStatic() && !root->stat && do not replace doc of a static */ if ( /* !md->isStatic() && !root->stat && do not replace doc of a static */
( (
md->documentation().isEmpty() || /* no docs yet */ md->documentation().isEmpty() || /* no docs yet */
...@@ -4656,6 +4685,7 @@ static void addMemberDocs(EntryNav *rootNav, ...@@ -4656,6 +4685,7 @@ static void addMemberDocs(EntryNav *rootNav,
) )
) && !root->doc.isEmpty() ) && !root->doc.isEmpty()
) )
#endif
{ {
//printf("overwrite!\n"); //printf("overwrite!\n");
md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocumentation(root->doc,root->docFile,root->docLine);
...@@ -4666,12 +4696,14 @@ static void addMemberDocs(EntryNav *rootNav, ...@@ -4666,12 +4696,14 @@ static void addMemberDocs(EntryNav *rootNav,
// md->briefDescription().data(),root->brief.data()); // md->briefDescription().data(),root->brief.data());
// brief descriptions inside a compound override the documentation // brief descriptions inside a compound override the documentation
// outside it // outside it
#if 0
if ( /* !md->isStatic() && !root->stat && do not replace doc of static */ if ( /* !md->isStatic() && !root->stat && do not replace doc of static */
( (
md->briefDescription().isEmpty() || /* no docs yet */ md->briefDescription().isEmpty() || /* no docs yet */
!rootNav->parent()->name().isEmpty() /* member of a class */ !rootNav->parent()->name().isEmpty() /* member of a class */
) && !root->brief.isEmpty() ) && !root->brief.isEmpty()
) )
#endif
{ {
//printf("overwrite!\n"); //printf("overwrite!\n");
md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
...@@ -5715,6 +5747,7 @@ static void findMember(EntryNav *rootNav, ...@@ -5715,6 +5747,7 @@ static void findMember(EntryNav *rootNav,
// root->argList ? (int)root->argList->count() : -1); // root->argList ? (int)root->argList->count() : -1);
// new related (member) function // new related (member) function
#if 0 // removed as it doesn't handle related template functions correctly
ArgumentList *tArgList = ArgumentList *tArgList =
getTemplateArgumentsFromName(scopeName+"::"+funcName,root->tArgLists); getTemplateArgumentsFromName(scopeName+"::"+funcName,root->tArgLists);
MemberDef *md=new MemberDef( MemberDef *md=new MemberDef(
...@@ -5722,7 +5755,37 @@ static void findMember(EntryNav *rootNav, ...@@ -5722,7 +5755,37 @@ static void findMember(EntryNav *rootNav,
funcType,funcName,funcArgs,exceptions, funcType,funcName,funcArgs,exceptions,
root->protection,root->virt,root->stat,TRUE, root->protection,root->virt,root->stat,TRUE,
mtype,tArgList,funcArgs.isEmpty() ? 0 : root->argList); mtype,tArgList,funcArgs.isEmpty() ? 0 : root->argList);
#endif
// first note that we pass:
// (root->tArgLists ? root->tArgLists->last() : 0)
// for the template arguments fo the new "member."
// this accurately reflects the template arguments of
// the related function, which don't have to do with
// those of the related class.
MemberDef *md=new MemberDef(
root->fileName,root->startLine,
funcType,funcName,funcArgs,exceptions,
root->protection,root->virt,root->stat,TRUE,
mtype,
(root->tArgLists ? root->tArgLists->last() : 0),
funcArgs.isEmpty() ? 0 : root->argList);
//
// we still have the problem that
// MemberDef::writeDocumentation() in memberdef.cpp
// writes the template argument list for the class,
// as if this member is a member of the class.
// fortunately, MemberDef::writeDocumentation() has
// a special mechanism that allows us to totally
// override the set of template argument lists that
// are printed. We use that and set it to the
// template argument lists of the related function.
//
md->setDefinitionTemplateParameterLists(root->tArgLists);
md->setTagInfo(rootNav->tagInfo()); md->setTagInfo(rootNav->tagInfo());
//printf("Related member name=`%s' decl=`%s' bodyLine=`%d'\n", //printf("Related member name=`%s' decl=`%s' bodyLine=`%d'\n",
// funcName.data(),funcDecl.data(),root->bodyLine); // funcName.data(),funcDecl.data(),root->bodyLine);
...@@ -6541,7 +6604,9 @@ static void findEnumDocumentation(EntryNav *rootNav) ...@@ -6541,7 +6604,9 @@ static void findEnumDocumentation(EntryNav *rootNav)
if (cd && cd->name()==className && md->isEnumerate()) if (cd && cd->name()==className && md->isEnumerate())
{ {
// documentation outside a compound overrides the documentation inside it // documentation outside a compound overrides the documentation inside it
#if 0
if (!md->documentation() || rootNav->parent()->name().isEmpty()) if (!md->documentation() || rootNav->parent()->name().isEmpty())
#endif
{ {
md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocumentation(root->doc,root->docFile,root->docLine);
md->setDocsForDefinition(!root->proto); md->setDocsForDefinition(!root->proto);
...@@ -6549,7 +6614,9 @@ static void findEnumDocumentation(EntryNav *rootNav) ...@@ -6549,7 +6614,9 @@ static void findEnumDocumentation(EntryNav *rootNav)
// brief descriptions inside a compound override the documentation // brief descriptions inside a compound override the documentation
// outside it // outside it
#if 0
if (!md->briefDescription() || !rootNav->parent()->name().isEmpty()) if (!md->briefDescription() || !rootNav->parent()->name().isEmpty())
#endif
{ {
md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
} }
...@@ -7374,12 +7441,16 @@ static void findDefineDocumentation(EntryNav *rootNav) ...@@ -7374,12 +7441,16 @@ static void findDefineDocumentation(EntryNav *rootNav)
{ {
if (md->memberType()==MemberDef::Define) if (md->memberType()==MemberDef::Define)
{ {
#if 0
if (md->documentation().isEmpty()) if (md->documentation().isEmpty())
#endif
{ {
md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocumentation(root->doc,root->docFile,root->docLine);
md->setDocsForDefinition(!root->proto); md->setDocsForDefinition(!root->proto);
} }
#if 0
if (md->briefDescription().isEmpty()) if (md->briefDescription().isEmpty())
#endif
{ {
md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
} }
...@@ -7416,12 +7487,16 @@ static void findDefineDocumentation(EntryNav *rootNav) ...@@ -7416,12 +7487,16 @@ static void findDefineDocumentation(EntryNav *rootNav)
if (fd && fd->absFilePath()==root->fileName) if (fd && fd->absFilePath()==root->fileName)
// doc and define in the same file assume they belong together. // doc and define in the same file assume they belong together.
{ {
#if 0
if (md->documentation().isEmpty()) if (md->documentation().isEmpty())
#endif
{ {
md->setDocumentation(root->doc,root->docFile,root->docLine); md->setDocumentation(root->doc,root->docFile,root->docLine);
md->setDocsForDefinition(!root->proto); md->setDocsForDefinition(!root->proto);
} }
#if 0
if (md->briefDescription().isEmpty()) if (md->briefDescription().isEmpty())
#endif
{ {
md->setBriefDescription(root->brief,root->briefFile,root->briefLine); md->setBriefDescription(root->brief,root->briefFile,root->briefLine);
} }
......
...@@ -184,7 +184,8 @@ void LatexGenerator::init() ...@@ -184,7 +184,8 @@ void LatexGenerator::init()
} }
else // use pdflatex for higher quality output else // use pdflatex for higher quality output
{ {
t << "all: clean refman.pdf" << endl << endl; t << "all: clean refman.pdf" << endl << endl
<< "pdf: refman.pdf" << endl << endl;
t << "refman.pdf: refman.tex" << endl; t << "refman.pdf: refman.tex" << endl;
t << "\tpdflatex refman.tex" << endl; t << "\tpdflatex refman.tex" << endl;
t << "\tmakeindex refman.idx" << endl; t << "\tmakeindex refman.idx" << endl;
......
...@@ -150,7 +150,7 @@ static bool writeDefArgumentList(OutputList &ol,ClassDef *cd, ...@@ -150,7 +150,7 @@ static bool writeDefArgumentList(OutputList &ol,ClassDef *cd,
// or use the following to put the function pointer as it appears in // or use the following to put the function pointer as it appears in
// the prototype. // the prototype.
// bool hasFuncPtrType=vp!=-1 && wp!=-1 && wp<vp; //bool hasFuncPtrType=vp!=-1 && wp!=-1 && wp<vp;
if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute if (!a->attrib.isEmpty() && !md->isObjCMethod()) // argument has an IDL attribute
{ {
...@@ -455,9 +455,9 @@ void MemberDefImpl::init(Definition *def, ...@@ -455,9 +455,9 @@ void MemberDefImpl::init(Definition *def,
initLines=0; initLines=0;
type=t; type=t;
if (mt==MemberDef::Typedef) type.stripPrefix("typedef "); if (mt==MemberDef::Typedef) type.stripPrefix("typedef ");
type.stripPrefix("struct "); // type.stripPrefix("struct ");
type.stripPrefix("class " ); // type.stripPrefix("class " );
type.stripPrefix("union " ); // type.stripPrefix("union " );
type=removeRedundantWhiteSpace(type); type=removeRedundantWhiteSpace(type);
args=a; args=a;
args=removeRedundantWhiteSpace(args); args=removeRedundantWhiteSpace(args);
...@@ -970,10 +970,11 @@ bool MemberDef::isBriefSectionVisible() const ...@@ -970,10 +970,11 @@ bool MemberDef::isBriefSectionVisible() const
makeResident(); makeResident();
LockingPtr<MemberDef> lock(this,this); LockingPtr<MemberDef> lock(this,this);
MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId]; MemberGroupInfo *info = Doxygen::memGrpInfoDict[m_impl->grpId];
//printf("name=%s m_impl->grpId=%d info=%p\n",name().data(),m_impl->grpId,info);
//QCString *pMemGrp = Doxygen::memberDocDict[grpId]; //QCString *pMemGrp = Doxygen::memberDocDict[grpId];
bool hasDocs = hasDocumentation() || bool hasDocs = hasDocumentation() ||
// part of a documented member group // part of a documented member group
(m_impl->grpId!=-1 && info && !info->doc.isEmpty()); (m_impl->grpId!=-1 && info && !(info->doc.isEmpty() && info->header.isEmpty()));
// only include static members with file/namespace scope if // only include static members with file/namespace scope if
// explicitly enabled in the config file // explicitly enabled in the config file
...@@ -1033,9 +1034,9 @@ bool MemberDef::isBriefSectionVisible() const ...@@ -1033,9 +1034,9 @@ bool MemberDef::isBriefSectionVisible() const
); );
//printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d" //printf("visibleIfStatic=%d visibleIfDocumented=%d visibleIfEnabled=%d"
// "visibleIfPrivate=%d visibleIfDocVirtual=%d visibltIfNotDefaultCDTor=%d " // "visibleIfPrivate=%d visibltIfNotDefaultCDTor=%d "
// "visibleIfFriendCompound=%d\n",visibleIfStatic,visibleIfDocumented, // "visibleIfFriendCompound=%d\n",visibleIfStatic,visibleIfDocumented,
// visibleIfEnabled,visibleIfPrivate,visibleIfDocVirtual,visibleIfNotDefaultCDTor, // visibleIfEnabled,visibleIfPrivate,visibleIfNotDefaultCDTor,
// visibleIfFriendCompound); // visibleIfFriendCompound);
bool visible = visibleIfStatic && visibleIfDocumented && bool visible = visibleIfStatic && visibleIfDocumented &&
...@@ -1222,7 +1223,7 @@ void MemberDef::writeDeclaration(OutputList &ol, ...@@ -1222,7 +1223,7 @@ void MemberDef::writeDeclaration(OutputList &ol,
} }
else else
{ {
ltype = ltype.left(i) + " { ... } " + ltype.right(ltype.length()-i-l); ltype = ltype.left(i) + " { ... } " + removeAnonymousScopes(ltype.right(ltype.length()-i-l));
linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype,TRUE); linkifyText(TextGeneratorOLImpl(ol),d,getBodyDef(),name(),ltype,TRUE);
} }
} }
...@@ -1575,7 +1576,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol, ...@@ -1575,7 +1576,7 @@ void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
} }
// get member name // get member name
QCString doxyName=name().copy(); QCString doxyName=name();
// prepend scope if there is any. TODO: make this optional for C only docs // prepend scope if there is any. TODO: make this optional for C only docs
if (scopeName) doxyName.prepend((QCString)scopeName+"::"); if (scopeName) doxyName.prepend((QCString)scopeName+"::");
QCString doxyArgs=argsString(); QCString doxyArgs=argsString();
......
...@@ -67,6 +67,7 @@ void MemberList::countDecMembers(bool countEnumValues) ...@@ -67,6 +67,7 @@ void MemberList::countDecMembers(bool countEnumValues)
MemberDef *md; MemberDef *md;
for (mli.toFirst();(md=mli.current());++mli) for (mli.toFirst();(md=mli.current());++mli)
{ {
//printf("MemberList::countDecMembers(md=%s,%d)\n",md->name().data(),md->isBriefSectionVisible());
if (md->isBriefSectionVisible()) if (md->isBriefSectionVisible())
{ {
switch(md->memberType()) switch(md->memberType())
...@@ -177,8 +178,12 @@ void MemberList::writePlainDeclarations(OutputList &ol, ...@@ -177,8 +178,12 @@ void MemberList::writePlainDeclarations(OutputList &ol,
{ {
//printf("----- writePlainDeclaration() ----\n"); //printf("----- writePlainDeclaration() ----\n");
countDecMembers(); countDecMembers();
if (numDecMembers()==0) return; // no members in this list if (numDecMembers()==0)
//printf("----> writePlainDeclaration() numDecMembers()=%d\n", {
//printf(" --> no members!\n");
return; // no members in this list
}
//printf(" --> writePlainDeclaration() numDecMembers()=%d\n",
// numDecMembers()); // numDecMembers());
ol.pushGeneratorState(); ol.pushGeneratorState();
......
...@@ -1000,7 +1000,7 @@ STARTDOCSYMS ^{B}"##"/[^#] ...@@ -1000,7 +1000,7 @@ STARTDOCSYMS ^{B}"##"/[^#]
// prepend scope in case of nested classes // prepend scope in case of nested classes
if (current_root->section&Entry::SCOPE_MASK) if (current_root->section&Entry::SCOPE_MASK)
{ {
printf("*** Prepending scope %s to class %s\n",current_root->name.data(),current->name.data()); //printf("*** Prepending scope %s to class %s\n",current_root->name.data(),current->name.data());
current->name.prepend(current_root->name+"::"); current->name.prepend(current_root->name+"::");
} }
......
...@@ -114,6 +114,7 @@ static bool insideD = FALSE; //!< processing D code? ...@@ -114,6 +114,7 @@ static bool insideD = FALSE; //!< processing D code?
static bool insidePHP = FALSE; //!< processing PHP code? static bool insidePHP = FALSE; //!< processing PHP code?
static bool insideObjC = FALSE; //!< processing Objective C code? static bool insideObjC = FALSE; //!< processing Objective C code?
static bool insideCli = FALSE; //!< processing C++/CLI code? static bool insideCli = FALSE; //!< processing C++/CLI code?
static bool insideJS = FALSE; //!< processing JavaScript code?
static bool insideCppQuote = FALSE; static bool insideCppQuote = FALSE;
static bool insideProtocolList = FALSE; static bool insideProtocolList = FALSE;
...@@ -330,6 +331,7 @@ static void setContext() ...@@ -330,6 +331,7 @@ static void setContext()
insideD = langExt==SrcLangExt_D; insideD = langExt==SrcLangExt_D;
insidePHP = langExt==SrcLangExt_PHP; insidePHP = langExt==SrcLangExt_PHP;
insideObjC = langExt==SrcLangExt_ObjC; insideObjC = langExt==SrcLangExt_ObjC;
insideJS = langExt==SrcLangExt_JS;
if ( insidePHP ) if ( insidePHP )
{ {
useOverrideCommands = TRUE; useOverrideCommands = TRUE;
...@@ -506,6 +508,23 @@ static void addKnRArgInfo(const QCString &type,const QCString &name, ...@@ -506,6 +508,23 @@ static void addKnRArgInfo(const QCString &type,const QCString &name,
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void fixArgumentListForJavaScript(ArgumentList *al)
{
if (al==0) return;
ArgumentListIterator ali(*al);
Argument *a;
for (ali.toFirst();(a=ali.current());++ali)
{
if (!a->type.isEmpty() && a->name.isEmpty())
{ // a->type is actually the (typeless) parameter name, so move it
a->name=a->type;
a->type.resize(0);
}
}
}
/* ----------------------------------------------------------------- */ /* ----------------------------------------------------------------- */
#undef YY_INPUT #undef YY_INPUT
#define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
...@@ -750,6 +769,9 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -750,6 +769,9 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
unput(*yytext); unput(*yytext);
BEGIN( FindMembers ); BEGIN( FindMembers );
} }
<FindMembers>"<?php" { // PHP code with unsupported extension?
insidePHP = TRUE;
}
<FindMembersPHP>"<?"("php"?) { // PHP code start <FindMembersPHP>"<?"("php"?) { // PHP code start
BEGIN( FindMembers ); BEGIN( FindMembers );
} }
...@@ -902,7 +924,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -902,7 +924,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
} }
<CliPropertyType>"{" { <CliPropertyType>"{" {
curlyCount=0; curlyCount=0;
printf("event: '%s' '%s'\n",current->type.data(),current->name.data()); //printf("event: '%s' '%s'\n",current->type.data(),current->name.data());
BEGIN( CSAccessorDecl ); BEGIN( CSAccessorDecl );
} }
<CliPropertyType>";" { <CliPropertyType>";" {
...@@ -1762,13 +1784,21 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -1762,13 +1784,21 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
insideTryBlock=FALSE; insideTryBlock=FALSE;
BEGIN(TryFunctionBlock); BEGIN(TryFunctionBlock);
} }
else if (insideJS && strcmp(yytext,"var")==0)
{ // javascript variable
current->type="var";
}
else if (insideJS && strcmp(yytext,"function")==0)
{ // javascript function
current->type="function";
}
else else
{ {
if (YY_START==FindMembers) if (YY_START==FindMembers)
{ {
addType( current ) ; addType( current ) ;
} }
bool javaLike = insideJava || insideCS || insideD || insidePHP; bool javaLike = insideJava || insideCS || insideD || insidePHP || insideJS;
if (javaLike && strcmp(yytext,"public")==0) if (javaLike && strcmp(yytext,"public")==0)
{ {
current->protection = Public; current->protection = Public;
...@@ -1781,6 +1811,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -1781,6 +1811,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
{ {
current->protection = Private; current->protection = Private;
} }
else if (javaLike && strcmp(yytext,"static")==0)
{
if (YY_START==FindMembers)
current->name = yytext;
else
current->name += yytext;
current->stat = TRUE;
}
else else
{ {
if (YY_START==FindMembers) if (YY_START==FindMembers)
...@@ -2866,7 +2904,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -2866,7 +2904,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
current = new Entry(*current); current = new Entry(*current);
if (current->section==Entry::NAMESPACE_SEC || if (current->section==Entry::NAMESPACE_SEC ||
(current->spec==Entry::Interface) || (current->spec==Entry::Interface) ||
insideJava || insidePHP || insideCS || insideD insideJava || insidePHP || insideCS || insideD || insideJS
) )
{ // namespaces and interfaces and java classes ends with a closing bracket without semicolon { // namespaces and interfaces and java classes ends with a closing bracket without semicolon
current->reset(); current->reset();
...@@ -2902,6 +2940,10 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -2902,6 +2940,10 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
BEGIN( TypedefName ); BEGIN( TypedefName );
} }
} }
<TypedefName>("const"|"volatile"){BN} { // late "const" or "volatile" keyword
lineCount();
current->type.prepend(yytext);
}
<TypedefName>{ID} { <TypedefName>{ID} {
if (current->section == Entry::ENUM_SEC) if (current->section == Entry::ENUM_SEC)
{ {
...@@ -3285,6 +3327,10 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -3285,6 +3327,10 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
*copyArgString+=*yytext; *copyArgString+=*yytext;
fullArgString+=*yytext; fullArgString+=*yytext;
stringToArgumentList(fullArgString,current->argList); stringToArgumentList(fullArgString,current->argList);
if (insideJS)
{
fixArgumentListForJavaScript(current->argList);
}
handleParametersCommentBlocks(current->argList); handleParametersCommentBlocks(current->argList);
/* remember the current documentation block, since /* remember the current documentation block, since
...@@ -4193,7 +4239,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -4193,7 +4239,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
roundCount=0; roundCount=0;
BEGIN(SkipUnionSwitch); BEGIN(SkipUnionSwitch);
} }
else if ((insideJava || insidePHP) && (strcmp(yytext,"implements")==0 || strcmp(yytext,"extends")==0)) else if ((insideJava || insidePHP || insideJS) && (strcmp(yytext,"implements")==0 || strcmp(yytext,"extends")==0))
{ {
current->type.resize(0); current->type.resize(0);
baseProt=Public; baseProt=Public;
...@@ -4362,7 +4408,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -4362,7 +4408,14 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
{ {
if (current->section==Entry::NAMESPACE_SEC) // allow reopening of anonymous namespaces if (current->section==Entry::NAMESPACE_SEC) // allow reopening of anonymous namespaces
{ {
current->name.sprintf("@%d",anonNSCount); if (Config_getBool("EXTRACT_ANON_NSPACES")) // use visible name
{
current->name="anonymous_namespace{"+stripPath(current->fileName)+"}";
}
else // use invisible name
{
current->name.sprintf("@%d",anonNSCount);
}
} }
else else
{ {
...@@ -4573,12 +4626,23 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -4573,12 +4626,23 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
//printf("Start doc block at %d\n",yyLineNr); //printf("Start doc block at %d\n",yyLineNr);
removeSlashes=(yytext[1]=='/'); removeSlashes=(yytext[1]=='/');
tmpDocType=-1; tmpDocType=-1;
#if 0
if (YY_START!=SkipCurly) if (YY_START!=SkipCurly)
{ {
current->doc.resize(0); current->doc.resize(0);
}
#endif
if (!current->doc.isEmpty())
{
current->doc+="\n\n";
}
else
{
current->docLine = yyLineNr; current->docLine = yyLineNr;
current->docFile = yyFileName; current->docFile = yyFileName;
} }
//
lastDocContext = YY_START; lastDocContext = YY_START;
if (current_root->section & Entry::SCOPE_MASK) if (current_root->section & Entry::SCOPE_MASK)
{ {
...@@ -4597,6 +4661,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -4597,6 +4661,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
current->briefLine = yyLineNr; current->briefLine = yyLineNr;
current->briefFile = yyFileName; current->briefFile = yyFileName;
} }
#if 0
if (!docBlockInBody) if (!docBlockInBody)
{ {
current->doc.resize(0); current->doc.resize(0);
...@@ -4605,6 +4670,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -4605,6 +4670,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
current->brief.resize(0); current->brief.resize(0);
} }
} }
#endif
startCommentBlock(FALSE); startCommentBlock(FALSE);
BEGIN( DocBlock ); BEGIN( DocBlock );
} }
...@@ -4631,6 +4697,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -4631,6 +4697,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
current->briefLine = yyLineNr; current->briefLine = yyLineNr;
current->briefFile = yyFileName; current->briefFile = yyFileName;
} }
#if 0
if (!docBlockInBody) if (!docBlockInBody)
{ {
current->doc.resize(0); current->doc.resize(0);
...@@ -4639,16 +4706,19 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -4639,16 +4706,19 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
current->brief.resize(0); current->brief.resize(0);
} }
} }
#endif
startCommentBlock(FALSE); startCommentBlock(FALSE);
BEGIN( DocBlock ); BEGIN( DocBlock );
} }
<FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"//!" { <FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"//!" {
#if 0
if (YY_START!=SkipCurly) if (YY_START!=SkipCurly)
{ {
current->brief.resize(0); current->brief.resize(0);
current->briefFile=yyFileName; current->briefFile=yyFileName;
current->briefLine=yyLineNr; current->briefLine=yyLineNr;
} }
#endif
tmpDocType=-1; tmpDocType=-1;
lastDocContext = YY_START; lastDocContext = YY_START;
if (current_root->section & Entry::SCOPE_MASK) if (current_root->section & Entry::SCOPE_MASK)
...@@ -4663,16 +4733,18 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -4663,16 +4733,18 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
docBlockInBody = YY_START==SkipCurly; docBlockInBody = YY_START==SkipCurly;
docBlockAutoBrief = FALSE; docBlockAutoBrief = FALSE;
docBlock.resize(0); docBlock.resize(0);
startCommentBlock(TRUE); startCommentBlock(current->brief.isEmpty());
BEGIN( DocLine ); BEGIN( DocLine );
} }
<FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"///"/[^/] { <FindMembers,FindFields,MemberSpec,SkipCurly,FuncQual,Operator,ClassVar,Bases,OldStyleArgs>"///"/[^/] {
#if 0
if (YY_START!=SkipCurly) if (YY_START!=SkipCurly)
{ {
current->brief.resize(0); current->brief.resize(0);
current->briefFile=yyFileName; current->briefFile=yyFileName;
current->briefLine=yyLineNr; current->briefLine=yyLineNr;
} }
#endif
tmpDocType=-1; tmpDocType=-1;
lastDocContext = YY_START; lastDocContext = YY_START;
if (current_root->section & Entry::SCOPE_MASK) if (current_root->section & Entry::SCOPE_MASK)
...@@ -4687,7 +4759,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -4687,7 +4759,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
docBlockInBody = YY_START==SkipCurly; docBlockInBody = YY_START==SkipCurly;
docBlockAutoBrief = FALSE; docBlockAutoBrief = FALSE;
docBlock.resize(0); docBlock.resize(0);
startCommentBlock(TRUE); startCommentBlock(current->brief.isEmpty());
BEGIN( DocLine ); BEGIN( DocLine );
} }
<FindMembers>"extern"{BN}*"\"C"("++")?"\""{BN}*("{")? { <FindMembers>"extern"{BN}*"\"C"("++")?"\""{BN}*("{")? {
...@@ -4777,7 +4849,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?) ...@@ -4777,7 +4849,7 @@ TYPEDEFPREFIX (("typedef"{BN}+)?)((("volatile"|"const"){BN}+)?)
} }
<DocLine>[^\n]*/"\n" { // whole line <DocLine>[^\n]*/"\n" { // whole line
docBlock+=yytext; docBlock+=yytext;
handleCommentBlock(docBlock,TRUE); handleCommentBlock(docBlock,current->brief.isEmpty());
BEGIN( docBlockContext ); BEGIN( docBlockContext );
} }
...@@ -5148,7 +5220,7 @@ static void parseCompounds(Entry *rt) ...@@ -5148,7 +5220,7 @@ static void parseCompounds(Entry *rt)
BEGIN( FindMembers ) ; BEGIN( FindMembers ) ;
current_root = ce ; current_root = ce ;
yyFileName = ce->fileName; yyFileName = ce->fileName;
setContext(); //setContext();
yyLineNr = ce->startLine ; yyLineNr = ce->startLine ;
insideObjC = ce->objc; insideObjC = ce->objc;
//printf("---> Inner block starts at line %d objC=%d\n",yyLineNr,insideObjC); //printf("---> Inner block starts at line %d objC=%d\n",yyLineNr,insideObjC);
...@@ -5160,15 +5232,12 @@ static void parseCompounds(Entry *rt) ...@@ -5160,15 +5232,12 @@ static void parseCompounds(Entry *rt)
// set default protection based on the compound type // set default protection based on the compound type
if( ce->section==Entry::CLASS_SEC ) // class if( ce->section==Entry::CLASS_SEC ) // class
{ {
if (
ce->fileName.right(4)==".php" || if (insidePHP || insideD || insideJS)
ce->fileName.right(4)==".inc" ||
ce->fileName.right(2)==".d"
)
{ {
current->protection = protection = Public ; current->protection = protection = Public ;
} }
else if (ce->fileName.right(5)==".java") else if (insideJava)
{ {
current->protection = protection = Package ; current->protection = protection = Package ;
} }
......
...@@ -73,7 +73,7 @@ void TextDocVisitor::filter(const char *str) ...@@ -73,7 +73,7 @@ void TextDocVisitor::filter(const char *str)
{ {
case '\n': m_t << " "; break; case '\n': m_t << " "; break;
case '"': m_t << "&quot;"; break; case '"': m_t << "&quot;"; break;
case '\'': m_t << "&apos;"; break; case '\'': m_t << "&#39;"; break;
case '<': m_t << "&lt;"; break; case '<': m_t << "&lt;"; break;
case '>': m_t << "&gt;"; break; case '>': m_t << "&gt;"; break;
case '&': m_t << "&amp;"; break; case '&': m_t << "&amp;"; break;
......
...@@ -163,8 +163,8 @@ QCString removeAnonymousScopes(const QCString &s) ...@@ -163,8 +163,8 @@ QCString removeAnonymousScopes(const QCString &s)
return result; return result;
} }
// replace anonymous scopes with __anonymous__ // replace anonymous scopes with __anonymous__ or replacement if provided
QCString replaceAnonymousScopes(const QCString &s) QCString replaceAnonymousScopes(const QCString &s,const char *replacement)
{ {
QCString result; QCString result;
if (s.isEmpty()) return result; if (s.isEmpty()) return result;
...@@ -174,7 +174,14 @@ QCString replaceAnonymousScopes(const QCString &s) ...@@ -174,7 +174,14 @@ QCString replaceAnonymousScopes(const QCString &s)
while ((i=re.match(s,p,&l))!=-1) while ((i=re.match(s,p,&l))!=-1)
{ {
result+=s.mid(p,i-p); result+=s.mid(p,i-p);
result+="__anonymous__"; if (replacement)
{
result+=replacement;
}
else
{
result+="__anonymous__";
}
p=i+l; p=i+l;
} }
result+=s.right(sl-p); result+=s.right(sl-p);
...@@ -4556,6 +4563,8 @@ QCString escapeCharsInString(const char *name,bool allowDots) ...@@ -4556,6 +4563,8 @@ QCString escapeCharsInString(const char *name,bool allowDots)
case '!': result+="_9"; break; case '!': result+="_9"; break;
case ',': result+="_00"; break; case ',': result+="_00"; break;
case ' ': result+="_01"; break; case ' ': result+="_01"; break;
case '{': result+="_02"; break;
case '}': result+="_03"; break;
default: default:
if (caseSenseNames || !isupper(c)) if (caseSenseNames || !isupper(c))
{ {
...@@ -4654,6 +4663,7 @@ QCString convertNameToFile(const char *name,bool allowDots) ...@@ -4654,6 +4663,7 @@ QCString convertNameToFile(const char *name,bool allowDots)
#endif #endif
result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir)); result.prepend(QCString().sprintf("d%x/d%02x/",l1Dir,l2Dir));
} }
//printf("*** convertNameToFile(%s)->%s\n",name,result.data());
return result; return result;
} }
...@@ -4821,12 +4831,6 @@ QCString stripScope(const char *name) ...@@ -4821,12 +4831,6 @@ QCString stripScope(const char *name)
} }
/*! Convert nibble (range 0..15) to hex char */
//static char nibbleToHex(int n)
//{
// return (n < 10) ? ('0'+n) : ('a'+n-10);
//}
/*! Converts a string to an XML-encoded string */ /*! Converts a string to an XML-encoded string */
QCString convertToXML(const char *s) QCString convertToXML(const char *s)
{ {
...@@ -4843,19 +4847,7 @@ QCString convertToXML(const char *s) ...@@ -4843,19 +4847,7 @@ QCString convertToXML(const char *s)
case '&': result+="&amp;"; break; case '&': result+="&amp;"; break;
case '\'': result+="&apos;"; break; case '\'': result+="&apos;"; break;
case '"': result+="&quot;"; break; case '"': result+="&quot;"; break;
default: default: result+=c; break;
//if (c<0)
//{ <- this doesn't work for languages that use
// characters with codes beyond 255
// result+=(QCString)"&#x" +
// nibbleToHex((((uchar)c)>>4)&0xf)+
// nibbleToHex(c&0xf)+";";
//}
//else
//{
result+=c;
//}
break;
} }
} }
return result; return result;
...@@ -4864,7 +4856,23 @@ QCString convertToXML(const char *s) ...@@ -4864,7 +4856,23 @@ QCString convertToXML(const char *s)
/*! Converts a string to a HTML-encoded string */ /*! Converts a string to a HTML-encoded string */
QCString convertToHtml(const char *s) QCString convertToHtml(const char *s)
{ {
return convertToXML(s); QCString result;
if (s==0) return result;
const char *p=s;
char c;
while ((c=*p++))
{
switch (c)
{
case '<': result+="&lt;"; break;
case '>': result+="&gt;"; break;
case '&': result+="&amp;"; break;
case '\'': result+="&#39;"; break;
case '"': result+="&quot;"; break;
default: result+=c; break;
}
}
return result;
} }
/*! Returns the standard string that is generated when the \\overload /*! Returns the standard string that is generated when the \\overload
...@@ -5304,7 +5312,7 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle, ...@@ -5304,7 +5312,7 @@ PageDef *addRelatedPage(const char *name,const QCString &ptitle,
if ((pd=Doxygen::pageSDict->find(name)) && !tagInfo) if ((pd=Doxygen::pageSDict->find(name)) && !tagInfo)
{ {
// append documentation block to the page. // append documentation block to the page.
pd->setDocumentation(pd->documentation()+"\n\n"+doc,fileName,startLine); pd->setDocumentation(doc,fileName,startLine);
//printf("Adding page docs `%s' pi=%p name=%s\n",doc.data(),pi,name); //printf("Adding page docs `%s' pi=%p name=%s\n",doc.data(),pi,name);
} }
else // new page else // new page
...@@ -5999,8 +6007,8 @@ SrcLangExt getLanguageFromFileName(const QCString fileName) ...@@ -5999,8 +6007,8 @@ SrcLangExt getLanguageFromFileName(const QCString fileName)
extLookup.insert(".odl", new int(SrcLangExt_IDL)); extLookup.insert(".odl", new int(SrcLangExt_IDL));
extLookup.insert(".ddl", new int(SrcLangExt_IDL)); extLookup.insert(".ddl", new int(SrcLangExt_IDL));
extLookup.insert(".java", new int(SrcLangExt_Java)); extLookup.insert(".java", new int(SrcLangExt_Java));
extLookup.insert(".jsl", new int(SrcLangExt_Java)); extLookup.insert(".as", new int(SrcLangExt_JS));
extLookup.insert(".as", new int(SrcLangExt_Java)); extLookup.insert(".js", new int(SrcLangExt_JS));
extLookup.insert(".cs", new int(SrcLangExt_CSharp)); extLookup.insert(".cs", new int(SrcLangExt_CSharp));
extLookup.insert(".d", new int(SrcLangExt_D)); extLookup.insert(".d", new int(SrcLangExt_D));
extLookup.insert(".php", new int(SrcLangExt_PHP)); extLookup.insert(".php", new int(SrcLangExt_PHP));
......
...@@ -92,6 +92,7 @@ enum SrcLangExt ...@@ -92,6 +92,7 @@ enum SrcLangExt
SrcLangExt_PHP = 0x080, SrcLangExt_PHP = 0x080,
SrcLangExt_ObjC = 0x100, SrcLangExt_ObjC = 0x100,
SrcLangExt_Cpp = 0x200, SrcLangExt_Cpp = 0x200,
SrcLangExt_JS = 0x400,
}; };
//-------------------------------------------------------------------- //--------------------------------------------------------------------
...@@ -215,7 +216,7 @@ int getPrefixIndex(const QCString &name); ...@@ -215,7 +216,7 @@ int getPrefixIndex(const QCString &name);
QCString removeAnonymousScopes(const QCString &s); QCString removeAnonymousScopes(const QCString &s);
QCString replaceAnonymousScopes(const QCString &s); QCString replaceAnonymousScopes(const QCString &s,const char *replacement=0);
void initClassHierarchy(ClassSDict *cl); void initClassHierarchy(ClassSDict *cl);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment