From d25d58214567928fe15016f49b3be819aca0703f Mon Sep 17 00:00:00 2001 From: Dimitri van Heesch Date: Sun, 26 Oct 2003 21:03:52 +0000 Subject: Release-1.3.4-20031026 --- INSTALL | 4 +- Makefile.in | 7 +- Makefile.win_make.in | 1 + Makefile.win_nmake.in | 3 + README | 4 +- VERSION | 2 +- configure | 5 +- libmd5/Makefile.in | 16 ++ libmd5/libmd5.pro.in | 10 + libmd5/md5.c | 565 ++++++++++++++++++++++++++++++++++++++++++++++ libmd5/md5.h | 225 ++++++++++++++++++ libmd5/md5_loc.h | 106 +++++++++ packages/rpm/doxygen.spec | 2 +- src/dot.cpp | 406 ++++++++++++++++++++------------- src/dot.h | 18 +- src/doxygen.pro.in | 14 +- src/htmlgen.cpp | 2 +- src/index.cpp | 4 +- src/latexdocvisitor.cpp | 10 +- src/libdoxygen.pro.in | 1 + src/mandocvisitor.cpp | 2 + src/rtfdocvisitor.cpp | 3 +- src/scanner.l | 173 ++++++++++++-- src/search.php | 4 + src/search_php.h | 4 + src/translator_kr.h | 2 +- 26 files changed, 1386 insertions(+), 207 deletions(-) create mode 100644 libmd5/Makefile.in create mode 100644 libmd5/libmd5.pro.in create mode 100644 libmd5/md5.c create mode 100644 libmd5/md5.h create mode 100644 libmd5/md5_loc.h diff --git a/INSTALL b/INSTALL index 1380346..a2f15a9 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,7 @@ -DOXYGEN Version 1.3.4-20031019 +DOXYGEN Version 1.3.4-20031026 Please read the installation section of the manual (http://www.doxygen.org/install.html) for instructions. -------- -Dimitri van Heesch (19 October 2003) +Dimitri van Heesch (26 October 2003) diff --git a/Makefile.in b/Makefile.in index 3a07b16..f668893 100644 --- a/Makefile.in +++ b/Makefile.in @@ -8,6 +8,7 @@ clean: FORCE cd qtools ; $(MAKE) clean cd src ; $(MAKE) clean cd libpng ; $(MAKE) clean + cd libmd5 ; $(MAKE) clean cd addon/doxywizard ; $(MAKE) clean cd addon/doxmlparser/src ; $(MAKE) clean cd addon/doxmlparser/test ; $(MAKE) clean @@ -18,6 +19,7 @@ clean: FORCE distclean: clean cd src ; $(MAKE) distclean cd libpng ; $(MAKE) distclean + cd libmd5 ; $(MAKE) distclean cd addon/doxywizard ; $(MAKE) distclean cd addon/doxmlparser/src ; $(MAKE) distclean cd addon/doxmlparser/test ; $(MAKE) distclean @@ -30,9 +32,10 @@ distclean: clean -rm -f src/Makefile.doxygen src/Makefile.libdoxygen -rm -f src/Makefile.doxytag src/Makefile.libdoxycfg -rm -f libpng/Makefile.libpng + -rm -f libmd5/Makefile.libmd5 -rm -f Makefile qtools/Makefile src/Makefile examples/Makefile doc/Makefile -rm -f .makeconfig .tmakeconfig - -rm -f src/doxygen.pro src/libdoxygen.pro src/doxytag.pro qtools/qtools.pro src/libdoxycfg.pro libpng/libpng.pro + -rm -f src/doxygen.pro src/libdoxygen.pro src/doxytag.pro qtools/qtools.pro src/libdoxycfg.pro libpng/libpng.pro libmd5/libmd5.pro -rm -f src/version.cpp -rm -r addon/doxywizard/Makefile -rm -f addon/doxywizard/Makefile.doxywizard @@ -71,7 +74,7 @@ pdf: docs cd latex ; $(MAKE) archive: clean - tar zcvf dx`date +%y%m%d`.tgz Doxyfile libpng addon tmake doc wintools examples bin lib objects \ + tar zcvf dx`date +%y%m%d`.tgz Doxyfile libpng libmd5 addon tmake doc wintools examples bin lib objects \ qtools src configure configure.bin Makefile.in Makefile.win_nmake.in \ Makefile.win_make.in INSTALL make.bat LANGUAGE.HOWTO LICENSE PLATFORMS \ VERSION packages diff --git a/Makefile.win_make.in b/Makefile.win_make.in index 17c93a9..8635696 100644 --- a/Makefile.win_make.in +++ b/Makefile.win_make.in @@ -1,6 +1,7 @@ all: src\version.cpp set TMAKEPATH=$(TMAKEPATH) & cd qtools & $(MAKE) set TMAKEPATH=$(TMAKEPATH) & cd libpng & $(MAKE) + set TMAKEPATH=$(TMAKEPATH) & cd libmd5 & $(MAKE) set TMAKEPATH=$(TMAKEPATH) & cd src & $(MAKE) clean: diff --git a/Makefile.win_nmake.in b/Makefile.win_nmake.in index 4a2ff78..d618b6c 100644 --- a/Makefile.win_nmake.in +++ b/Makefile.win_nmake.in @@ -6,6 +6,9 @@ all: src\version.cpp cd libpng $(MAKE) cd .. + cd libmd5 + $(MAKE) + cd .. cd src $(MAKE) diff --git a/README b/README index 1b1dc93..84a1061 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -DOXYGEN Version 1.3.4_20031019 +DOXYGEN Version 1.3.4_20031026 Please read INSTALL for compilation instructions. @@ -17,4 +17,4 @@ to subscribe to the lists or to visit the archives. Enjoy, -Dimitri van Heesch (dimitri@stack.nl) (19 October 2003) +Dimitri van Heesch (dimitri@stack.nl) (26 October 2003) diff --git a/VERSION b/VERSION index a5dbbe7..00a63fb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.3.4-20031019 +1.3.4-20031026 diff --git a/configure b/configure index 0afd55c..df7b481 100755 --- a/configure +++ b/configure @@ -427,7 +427,7 @@ TMAKE_CXXFLAGS += -DENGLISH_ONLY EOF fi -f_inmakefiles="Makefile.in qtools/Makefile.in src/Makefile.in examples/Makefile.in doc/Makefile.in addon/doxywizard/Makefile.in addon/doxmlparser/src/Makefile.in addon/doxmlparser/test/Makefile.in addon/doxmlparser/examples/metrics/Makefile.in libpng/Makefile.in" +f_inmakefiles="Makefile.in qtools/Makefile.in src/Makefile.in examples/Makefile.in doc/Makefile.in addon/doxywizard/Makefile.in addon/doxmlparser/src/Makefile.in addon/doxmlparser/test/Makefile.in addon/doxmlparser/examples/metrics/Makefile.in libpng/Makefile.in libmd5/Makefile.in" for i in $f_inmakefiles ; do SRC=$i @@ -445,6 +445,7 @@ EOF echo "all: src/version.cpp " >> $DST echo " \$(MAKE) -C qtools" >> $DST echo " \$(MAKE) -C libpng" >> $DST + echo " \$(MAKE) -C libmd5" >> $DST echo " \$(MAKE) -C src" >> $DST if test $f_wizard = YES; then echo " \$(MAKE) -C addon/doxywizard" >> $DST @@ -460,7 +461,7 @@ EOF echo " Created $DST from $SRC..." done -f_inprofiles="qtools/qtools.pro.in src/libdoxygen.pro.in src/libdoxycfg.pro.in src/doxygen.pro.in src/doxytag.pro.in addon/doxywizard/doxywizard.pro.in addon/doxmlparser/src/doxmlparser.pro.in addon/doxmlparser/test/xmlparse.pro.in addon/doxmlparser/examples/metrics/metrics.pro.in libpng/libpng.pro.in" +f_inprofiles="qtools/qtools.pro.in src/libdoxygen.pro.in src/libdoxycfg.pro.in src/doxygen.pro.in src/doxytag.pro.in addon/doxywizard/doxywizard.pro.in addon/doxmlparser/src/doxmlparser.pro.in addon/doxmlparser/test/xmlparse.pro.in addon/doxmlparser/examples/metrics/metrics.pro.in libpng/libpng.pro.in libmd5/libmd5.pro.in" for i in $f_inprofiles ; do SRC=$i diff --git a/libmd5/Makefile.in b/libmd5/Makefile.in new file mode 100644 index 0000000..5f71b11 --- /dev/null +++ b/libmd5/Makefile.in @@ -0,0 +1,16 @@ +all: Makefile.libmd5 + $(MAKE) -f Makefile.libmd5 + +clean: Makefile.libmd5 + $(MAKE) -f Makefile.libmd5 clean + +distclean: clean + $(RM) -f Makefile.libmd5 libmd5.pro Makefile + +tmake: + $(ENV) $(PERL) $(TMAKE) libmd5.pro >Makefile.libmd5 + +Makefile.libmd5: libmd5.pro + $(ENV) $(PERL) $(TMAKE) libmd5.pro >Makefile.libmd5 + +install: diff --git a/libmd5/libmd5.pro.in b/libmd5/libmd5.pro.in new file mode 100644 index 0000000..8cf7118 --- /dev/null +++ b/libmd5/libmd5.pro.in @@ -0,0 +1,10 @@ +TEMPLATE = lib +CONFIG = warn_on staticlib $extraopts +HEADERS = md5.h md5_loc.h +SOURCES = md5.c +win32:INCLUDEPATH += . +win32-g++:TMAKE_CFLAGS += -D__CYGWIN__ -DALL_STATIC +DESTDIR = ../lib +TARGET = md5 +OBJECTS_DIR = ../objects + diff --git a/libmd5/md5.c b/libmd5/md5.c new file mode 100644 index 0000000..a667090 --- /dev/null +++ b/libmd5/md5.c @@ -0,0 +1,565 @@ +/* + * Functions to compute MD5 message digest of files or memory blocks + * according to the definition of MD5 in RFC 1321 from April 1992. + * Copyright (C) 1995, 1996 Free Software Foundation, Inc. NOTE: The + * canonical source of this file is maintained with the GNU C Library. + * Bugs can be reported to bug-glibc@prep.ai.mit.edu. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Written by Ulrich Drepper , 1995. + * Modified by Gray Watson , 1997. + * + * $Id$ + */ + +/* + * NOTE: during quick performance tests on a Sun Sparc Ultra 1 and an + * Alpha 255 300, these functions performed upwards of 3mb/sec + * including disk I/O time. + */ + +/* + * MD5 Test Suite from RFC1321: http://ds.internic.net:/rfc/rfc1321.txt + * + * MD5 ("") = d41d8cd98f00b204e9800998ecf8427e + * MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661 + * MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72 + * MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0 + * MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b + * MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = + * d174ab98d277d9f5a5611c2c9f419d9f + * MD5 ("123456789012345678901234567890123456789012345678901234567890123456 + * 78901234567890") = 57edf4a22be3c955ac49da2e2107b67a + */ + +#include +#include +#include + +#include "md5.h" +#include "md5_loc.h" + +#if LIB_VERSION_REQUIRED +static char *rcs_id = + "$Id$"; + +/* version id for the library */ +static char *version_id = "$MD5Version: 1.0.0 November-19-1997 $"; +#endif + +/****************************** local routines *******************************/ + +/* + * process_block + * + * DESCRIPTION: + * + * Process a block of bytes into a MD5 state structure. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * md5_p - Pointer to MD5 structure from which we are getting the result. + * + * buffer - A buffer of bytes whose MD5 signature we are calculating. + * + * buf_len - The length of the buffer. + */ +static void process_block(md5_t *md5_p, const void *buffer, + const unsigned int buf_len) +{ + md5_uint32 correct[16]; + const void *buf_p = buffer, *end_p; + unsigned int words_n; + md5_uint32 A, B, C, D; + + words_n = buf_len / sizeof(md5_uint32); + end_p = (char *)buf_p + words_n * sizeof(md5_uint32); + + A = md5_p->md_A; + B = md5_p->md_B; + C = md5_p->md_C; + D = md5_p->md_D; + + /* + * First increment the byte count. RFC 1321 specifies the possible + * length of the file up to 2^64 bits. Here we only compute the + * number of bytes with a double word increment. Modified to do + * this to better avoid overflows in the lower word -- Gray 10/97. + */ + if (md5_p->md_total[0] > MAX_MD5_UINT32 - buf_len) { + md5_p->md_total[1]++; + md5_p->md_total[0] -= (MAX_MD5_UINT32 - buf_len); + } + else { + md5_p->md_total[0] += buf_len; + } + + /* + * Process all bytes in the buffer with MD5_BLOCK bytes in each + * round of the loop. + */ + while (buf_p < end_p) { + md5_uint32 A_save, B_save, C_save, D_save; + md5_uint32 *corr_p = correct; + + A_save = A; + B_save = B; + C_save = C; + D_save = D; + + /* + * Before we start, one word to the strange constants. They are + * defined in RFC 1321 as + * + * T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..MD5_BLOCK + */ + + /* Round 1. */ + OP1 (A, B, C, D, buf_p, corr_p, 7, 0xd76aa478); + OP1 (D, A, B, C, buf_p, corr_p, 12, 0xe8c7b756); + OP1 (C, D, A, B, buf_p, corr_p, 17, 0x242070db); + OP1 (B, C, D, A, buf_p, corr_p, 22, 0xc1bdceee); + OP1 (A, B, C, D, buf_p, corr_p, 7, 0xf57c0faf); + OP1 (D, A, B, C, buf_p, corr_p, 12, 0x4787c62a); + OP1 (C, D, A, B, buf_p, corr_p, 17, 0xa8304613); + OP1 (B, C, D, A, buf_p, corr_p, 22, 0xfd469501); + OP1 (A, B, C, D, buf_p, corr_p, 7, 0x698098d8); + OP1 (D, A, B, C, buf_p, corr_p, 12, 0x8b44f7af); + OP1 (C, D, A, B, buf_p, corr_p, 17, 0xffff5bb1); + OP1 (B, C, D, A, buf_p, corr_p, 22, 0x895cd7be); + OP1 (A, B, C, D, buf_p, corr_p, 7, 0x6b901122); + OP1 (D, A, B, C, buf_p, corr_p, 12, 0xfd987193); + OP1 (C, D, A, B, buf_p, corr_p, 17, 0xa679438e); + OP1 (B, C, D, A, buf_p, corr_p, 22, 0x49b40821); + + /* Round 2. */ + OP234 (FG, A, B, C, D, correct[ 1], 5, 0xf61e2562); + OP234 (FG, D, A, B, C, correct[ 6], 9, 0xc040b340); + OP234 (FG, C, D, A, B, correct[ 11], 14, 0x265e5a51); + OP234 (FG, B, C, D, A, correct[ 0], 20, 0xe9b6c7aa); + OP234 (FG, A, B, C, D, correct[ 5], 5, 0xd62f105d); + OP234 (FG, D, A, B, C, correct[ 10], 9, 0x02441453); + OP234 (FG, C, D, A, B, correct[ 15], 14, 0xd8a1e681); + OP234 (FG, B, C, D, A, correct[ 4], 20, 0xe7d3fbc8); + OP234 (FG, A, B, C, D, correct[ 9], 5, 0x21e1cde6); + OP234 (FG, D, A, B, C, correct[ 14], 9, 0xc33707d6); + OP234 (FG, C, D, A, B, correct[ 3], 14, 0xf4d50d87); + OP234 (FG, B, C, D, A, correct[ 8], 20, 0x455a14ed); + OP234 (FG, A, B, C, D, correct[ 13], 5, 0xa9e3e905); + OP234 (FG, D, A, B, C, correct[ 2], 9, 0xfcefa3f8); + OP234 (FG, C, D, A, B, correct[ 7], 14, 0x676f02d9); + OP234 (FG, B, C, D, A, correct[ 12], 20, 0x8d2a4c8a); + + /* Round 3. */ + OP234 (FH, A, B, C, D, correct[ 5], 4, 0xfffa3942); + OP234 (FH, D, A, B, C, correct[ 8], 11, 0x8771f681); + OP234 (FH, C, D, A, B, correct[ 11], 16, 0x6d9d6122); + OP234 (FH, B, C, D, A, correct[ 14], 23, 0xfde5380c); + OP234 (FH, A, B, C, D, correct[ 1], 4, 0xa4beea44); + OP234 (FH, D, A, B, C, correct[ 4], 11, 0x4bdecfa9); + OP234 (FH, C, D, A, B, correct[ 7], 16, 0xf6bb4b60); + OP234 (FH, B, C, D, A, correct[ 10], 23, 0xbebfbc70); + OP234 (FH, A, B, C, D, correct[ 13], 4, 0x289b7ec6); + OP234 (FH, D, A, B, C, correct[ 0], 11, 0xeaa127fa); + OP234 (FH, C, D, A, B, correct[ 3], 16, 0xd4ef3085); + OP234 (FH, B, C, D, A, correct[ 6], 23, 0x04881d05); + OP234 (FH, A, B, C, D, correct[ 9], 4, 0xd9d4d039); + OP234 (FH, D, A, B, C, correct[ 12], 11, 0xe6db99e5); + OP234 (FH, C, D, A, B, correct[ 15], 16, 0x1fa27cf8); + OP234 (FH, B, C, D, A, correct[ 2], 23, 0xc4ac5665); + + /* Round 4. */ + OP234 (FI, A, B, C, D, correct[ 0], 6, 0xf4292244); + OP234 (FI, D, A, B, C, correct[ 7], 10, 0x432aff97); + OP234 (FI, C, D, A, B, correct[ 14], 15, 0xab9423a7); + OP234 (FI, B, C, D, A, correct[ 5], 21, 0xfc93a039); + OP234 (FI, A, B, C, D, correct[ 12], 6, 0x655b59c3); + OP234 (FI, D, A, B, C, correct[ 3], 10, 0x8f0ccc92); + OP234 (FI, C, D, A, B, correct[ 10], 15, 0xffeff47d); + OP234 (FI, B, C, D, A, correct[ 1], 21, 0x85845dd1); + OP234 (FI, A, B, C, D, correct[ 8], 6, 0x6fa87e4f); + OP234 (FI, D, A, B, C, correct[ 15], 10, 0xfe2ce6e0); + OP234 (FI, C, D, A, B, correct[ 6], 15, 0xa3014314); + OP234 (FI, B, C, D, A, correct[ 13], 21, 0x4e0811a1); + OP234 (FI, A, B, C, D, correct[ 4], 6, 0xf7537e82); + OP234 (FI, D, A, B, C, correct[ 11], 10, 0xbd3af235); + OP234 (FI, C, D, A, B, correct[ 2], 15, 0x2ad7d2bb); + OP234 (FI, B, C, D, A, correct[ 9], 21, 0xeb86d391); + + /* Add the starting values of the context. */ + A += A_save; + B += B_save; + C += C_save; + D += D_save; + } + + /* Put checksum in context given as argument. */ + md5_p->md_A = A; + md5_p->md_B = B; + md5_p->md_C = C; + md5_p->md_D = D; +} + +/* + * md5_get_result + * + * DESCRIPTION: + * + * Copy the resulting MD5 signature from MD5_P into the first 16 bytes + * (MD5_SIZE) of the result buffer. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * md5_p - Pointer to MD5 structure from which we are getting the result. + * + * result - A 16 byte buffer that will contain the MD5 signature. + */ +static void md5_get_result(const md5_t *md5_p, void *result) +{ + md5_uint32 hold; + void *res_p = result; + + hold = SWAP(md5_p->md_A); + memcpy(res_p, &hold, sizeof(md5_uint32)); + res_p = (char *)res_p + sizeof(md5_uint32); + + hold = SWAP(md5_p->md_B); + memcpy(res_p, &hold, sizeof(md5_uint32)); + res_p = (char *)res_p + sizeof(md5_uint32); + + hold = SWAP(md5_p->md_C); + memcpy(res_p, &hold, sizeof(md5_uint32)); + res_p = (char *)res_p + sizeof(md5_uint32); + + hold = SWAP(md5_p->md_D); + memcpy(res_p, &hold, sizeof(md5_uint32)); +} + +/***************************** exported routines *****************************/ + +/* + * md5_init + * + * DESCRIPTION: + * + * Initialize structure containing state of MD5 computation. (RFC 1321, + * 3.3: Step 3). This is for progressive MD5 calculations only. If + * you have the complete string available, md5_buffer should be used. + * md5_process should be called for each bunch of bytes and after the + * last process call, md5_finish should be called to get the + * signature. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * md5_p - Pointer to md5 structure that we are initializing. + */ +void md5_init(md5_t *md5_p) +{ + md5_p->md_A = 0x67452301; + md5_p->md_B = 0xefcdab89; + md5_p->md_C = 0x98badcfe; + md5_p->md_D = 0x10325476; + + md5_p->md_total[0] = 0; + md5_p->md_total[1] = 0; + md5_p->md_buf_len = 0; +} + +/* + * md5_process + * + * DESCRIPTION: + * + * This function is used to progressively calculate a MD5 signature some + * number of bytes at a time. If you have the complete string + * available, md5_buffer should be used. The MD5 structure should + * have been initialized with md5_init and after the last process + * call, md5_finish should be called to get the results. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * md5_p - Pointer to MD5 structure which we are progressively updating. + * + * buffer - A buffer of bytes whose MD5 signature we are calculating. + * + * buf_len - The length of the buffer. + */ +void md5_process(md5_t *md5_p, const void *buffer, + const unsigned int buf_len) +{ + unsigned int len = buf_len; + unsigned int in_block, add; + + /* + * When we already have some bytes in our internal buffer, copy some + * from the user to fill the block. + */ + if (md5_p->md_buf_len > 0) { + + in_block = md5_p->md_buf_len; + if (in_block + len > sizeof(md5_p->md_buffer)) { + add = sizeof(md5_p->md_buffer) - in_block; + } + else { + add = len; + } + + memcpy (md5_p->md_buffer + in_block, buffer, add); + md5_p->md_buf_len += add; + in_block += add; + + if (in_block > MD5_BLOCK_SIZE) { + process_block (md5_p, md5_p->md_buffer, in_block & ~BLOCK_SIZE_MASK); + /* the regions in the following copy operation will not overlap. */ + memcpy (md5_p->md_buffer, + md5_p->md_buffer + (in_block & ~BLOCK_SIZE_MASK), + in_block & BLOCK_SIZE_MASK); + md5_p->md_buf_len = in_block & BLOCK_SIZE_MASK; + } + + buffer = (const char *)buffer + add; + len -= add; + } + + /* process available complete blocks right from the user buffer */ + if (len > MD5_BLOCK_SIZE) { + process_block (md5_p, buffer, len & ~BLOCK_SIZE_MASK); + buffer = (const char *) buffer + (len & ~BLOCK_SIZE_MASK); + len &= BLOCK_SIZE_MASK; + } + + /* copy remaining bytes into the internal buffer */ + if (len > 0) { + memcpy (md5_p->md_buffer, buffer, len); + md5_p->md_buf_len = len; + } +} + +/* + * md5_finish + * + * DESCRIPTION: + * + * Finish a progressing MD5 calculation and copy the resulting MD5 + * signature into the result buffer which should be 16 bytes + * (MD5_SIZE). After this call, the MD5 structure is invalid. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * md5_p - Pointer to MD5 structure which we are finishing. + * + * signature - A 16 byte buffer that will contain the MD5 signature. + */ +void md5_finish(md5_t *md5_p, void *signature) +{ + md5_uint32 bytes, hold; + int pad; + + /* take yet unprocessed bytes into account */ + bytes = md5_p->md_buf_len; + + /* + * Count remaining bytes. Modified to do this to better avoid + * overflows in the lower word -- Gray 10/97. + */ + if (md5_p->md_total[0] > MAX_MD5_UINT32 - bytes) { + md5_p->md_total[1]++; + md5_p->md_total[0] -= (MAX_MD5_UINT32 - bytes); + } + else { + md5_p->md_total[0] += bytes; + } + + /* + * Pad the buffer to the next MD5_BLOCK-byte boundary. (RFC 1321, + * 3.1: Step 1). We need enough room for two size words and the + * bytes left in the buffer. For some reason even if we are equal + * to the block-size, we add an addition block of pad bytes. + */ + pad = MD5_BLOCK_SIZE - (sizeof(md5_uint32) * 2) - bytes; + if (pad <= 0) { + pad += MD5_BLOCK_SIZE; + } + + /* + * Modified from a fixed array to this assignment and memset to be + * more flexible with block-sizes -- Gray 10/97. + */ + if (pad > 0) { + /* some sort of padding start byte */ + md5_p->md_buffer[bytes] = (unsigned char)0x80; + if (pad > 1) { + memset (md5_p->md_buffer + bytes + 1, 0, pad - 1); + } + bytes += pad; + } + + /* put the 64-bit file length in _bits_ (i.e. *8) at the end of the buffer */ + hold = SWAP(md5_p->md_total[0] << 3); + memcpy(md5_p->md_buffer + bytes, &hold, sizeof(md5_uint32)); + bytes += sizeof(md5_uint32); + + /* shift the high word over by 3 and add in the top 3 bits from the low */ + hold = SWAP((md5_p->md_total[1] << 3) | (md5_p->md_total[0] >> 29)); + memcpy(md5_p->md_buffer + bytes, &hold, sizeof(md5_uint32)); + bytes += sizeof(md5_uint32); + + /* process last bytes, the padding chars, and size words */ + process_block(md5_p, md5_p->md_buffer, bytes); + md5_get_result(md5_p, signature); +} + +/* + * md5_buffer + * + * DESCRIPTION: + * + * This function is used to calculate a MD5 signature for a buffer of + * bytes. If you only have part of a buffer that you want to process + * then md5_init, md5_process, and md5_finish should be used. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * buffer - A buffer of bytes whose MD5 signature we are calculating. + * + * buf_len - The length of the buffer. + * + * signature - A 16 byte buffer that will contain the MD5 signature. + */ +void md5_buffer(const char *buffer, const unsigned int buf_len, + void *signature) +{ + md5_t md5; + + /* initialize the computation context */ + md5_init(&md5); + + /* process whole buffer but last buf_len % MD5_BLOCK bytes */ + md5_process(&md5, buffer, buf_len); + + /* put result in desired memory area */ + md5_finish(&md5, signature); +} + +/* + * md5_sig_to_string + * + * DESCRIPTION: + * + * Convert a MD5 signature in a 16 byte buffer into a hexadecimal string + * representation. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * signature - a 16 byte buffer that contains the MD5 signature. + * + * str - a string of charactes which should be at least 33 bytes long (2 + * characters per MD5 byte and 1 for the \0). + * + * str_len - the length of the string. + */ +void md5_sig_to_string(void *signature, char *str, const int str_len) +{ + unsigned char *sig_p; + char *str_p, *max_p; + unsigned int high, low; + + str_p = str; + max_p = str + str_len; + + for (sig_p = (unsigned char *)signature; + sig_p < (unsigned char *)signature + MD5_SIZE; + sig_p++) { + high = *sig_p / 16; + low = *sig_p % 16; + /* account for 2 chars */ + if (str_p + 1 >= max_p) { + break; + } + *str_p++ = HEX_STRING[high]; + *str_p++ = HEX_STRING[low]; + } + /* account for 2 chars */ + if (str_p < max_p) { + *str_p++ = '\0'; + } +} + +/* + * md5_sig_from_string + * + * DESCRIPTION: + * + * Convert a MD5 signature from a hexadecimal string representation into + * a 16 byte buffer. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * signature - A 16 byte buffer that will contain the MD5 signature. + * + * str - A string of charactes which _must_ be at least 32 bytes long (2 + * characters per MD5 byte). + */ +void md5_sig_from_string(void *signature, const char *str) +{ + unsigned char *sig_p; + const char *str_p; + char *hex; + unsigned int high, low, val; + + hex = HEX_STRING; + sig_p = signature; + + for (str_p = str; str_p < str + MD5_SIZE * 2; str_p += 2) { + high = strchr(hex, *str_p) - hex; + low = strchr(hex, *(str_p + 1)) - hex; + val = high * 16 + low; + *sig_p++ = val; + } +} diff --git a/libmd5/md5.h b/libmd5/md5.h new file mode 100644 index 0000000..6b35fc6 --- /dev/null +++ b/libmd5/md5.h @@ -0,0 +1,225 @@ +/* + * Declaration of functions and data types used for MD5 sum computing + * library functions. Copyright (C) 1995, 1996 Free Software + * Foundation, Inc. NOTE: The canonical source of this file is + * maintained with the GNU C Library. Bugs can be reported to + * bug-glibc@prep.ai.mit.edu. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * $Id$ + */ + +/* + * NOTE: during quick performance tests on a sun ultra and an alpha + * 255 300, the md5 libraries performed upwards of 3mb/sec. That + * included disk i/o on bobcat and panther. + */ + +#ifndef __MD5_H__ +#define __MD5_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Size of a standard MD5 signature in bytes. This definition is for + * external programs only. The MD5 routines themselves reference the + * signature as 4 unsigned 32-bit integers. + */ +#define MD5_SIZE 16 + +/* + * NOTE: the following is assumed to generate a 32-bit unsigned data + * type. + */ +typedef unsigned int md5_uint32; +#define MAX_MD5_UINT32 ((md5_uint32)4294967295U) + +/* + * The MD5 algorithm works on blocks of characters of 64 bytes. This + * is an internal value only and is not necessary for external use. + */ +#define MD5_BLOCK_SIZE 64 + +/* + * Structure to save state of computation between the single steps. + */ +typedef struct +{ + md5_uint32 md_A; /* accumulater 1 */ + md5_uint32 md_B; /* accumulater 2 */ + md5_uint32 md_C; /* accumulater 3 */ + md5_uint32 md_D; /* accumulater 4 */ + + md5_uint32 md_total[2]; /* totaling storage */ + md5_uint32 md_buf_len; /* length of the storage buffer */ + char md_buffer[MD5_BLOCK_SIZE * 2]; /* character storage buffer */ +} md5_t; + +/*<<<<<<<<<< The below prototypes are auto-generated by fillproto */ + +/* + * md5_init + * + * DESCRIPTION: + * + * Initialize structure containing state of MD5 computation. (RFC 1321, + * 3.3: Step 3). This is for progressive MD5 calculations only. If + * you have the complete string available, md5_buffer should be used. + * md5_process should be called for each bunch of bytes and after the + * last process call, md5_finish should be called to get the + * signature. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * md5_p - Pointer to md5 structure that we are initializing. + */ +extern +void md5_init(md5_t *md5_p); + +/* + * md5_process + * + * DESCRIPTION: + * + * This function is used to progressively calculate a MD5 signature some + * number of bytes at a time. If you have the complete string + * available, md5_buffer should be used. The MD5 structure should + * have been initialized with md5_init and after the last process + * call, md5_finish should be called to get the results. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * md5_p - Pointer to MD5 structure which we are progressively updating. + * + * buffer - A buffer of bytes whose MD5 signature we are calculating. + * + * buf_len - The length of the buffer. + */ +extern +void md5_process(md5_t *md5_p, const void *buffer, + const unsigned int buf_len); + +/* + * md5_finish + * + * DESCRIPTION: + * + * Finish a progressing MD5 calculation and copy the resulting MD5 + * signature into the result buffer which should be 16 bytes + * (MD5_SIZE). After this call, the MD5 structure is invalid. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * md5_p - Pointer to MD5 structure which we are finishing. + * + * signature - A 16 byte buffer that will contain the MD5 signature. + */ +extern +void md5_finish(md5_t *md5_p, void *signature); + +/* + * md5_buffer + * + * DESCRIPTION: + * + * This function is used to calculate a MD5 signature for a buffer of + * bytes. If you only have part of a buffer that you want to process + * then md5_init, md5_process, and md5_finish should be used. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * buffer - A buffer of bytes whose MD5 signature we are calculating. + * + * buf_len - The length of the buffer. + * + * signature - A 16 byte buffer that will contain the MD5 signature. + */ +extern +void md5_buffer(const char *buffer, const unsigned int buf_len, + void *signature); + +/* + * md5_sig_to_string + * + * DESCRIPTION: + * + * Convert a MD5 signature in a 16 byte buffer into a hexadecimal string + * representation. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * signature - a 16 byte buffer that contains the MD5 signature. + * + * str - a string of charactes which should be at least 33 bytes long (2 + * characters per MD5 byte and 1 for the \0). + * + * str_len - the length of the string. + */ +extern +void md5_sig_to_string(void *signature, char *str, const int str_len); + +/* + * md5_sig_from_string + * + * DESCRIPTION: + * + * Convert a MD5 signature from a hexadecimal string representation into + * a 16 byte buffer. + * + * RETURNS: + * + * None. + * + * ARGUMENTS: + * + * signature - A 16 byte buffer that will contain the MD5 signature. + * + * str - A string of charactes which _must_ be at least 32 bytes long (2 + * characters per MD5 byte). + */ +extern +void md5_sig_from_string(void *signature, const char *str); + +/*<<<<<<<<<< This is end of the auto-generated output from fillproto. */ + +#ifdef __cplusplus +} +#endif + +#endif /* ! __MD5_H__ */ diff --git a/libmd5/md5_loc.h b/libmd5/md5_loc.h new file mode 100644 index 0000000..03aeebf --- /dev/null +++ b/libmd5/md5_loc.h @@ -0,0 +1,106 @@ +/* + * Local defines for the md5 functions. + * + * $Id$ + */ + +/* + * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + * rights reserved. + * + * 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_LOC_H__ +#define __MD5_LOC_H__ + +#define HEX_STRING "0123456789abcdef" /* to convert to hex */ +#define BLOCK_SIZE_MASK (MD5_BLOCK_SIZE - 1) + +/* + * Define my endian-ness. Could not do in a portable manner using the + * include files -- grumble. + */ +#if defined(__alpha) || defined(WIN32) || defined(__i386__) +/* + * little endian + */ +#define SWAP(n) (n) +#endif + +#ifdef __sparc +/* + * big endian - big is better + */ +#define SWAP(n) \ + (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +#endif + +/* + * These are the four functions used in the four steps of the MD5 + * algorithm and defined in the RFC 1321. The first function is a + * little bit optimized (as found in Colin Plumbs public domain + * implementation). + */ +/* #define FF(b, c, d) ((b & c) | (~b & d)) */ +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF(d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d)) + +/* + * It is unfortunate that C does not provide an operator for cyclic + * rotation. Hope the C compiler is smart enough. -- Modified to + * remove the w = at the front - Gray 2/97 + */ +#define CYCLIC(w, s) ((w << s) | (w >> (32 - s))) + +/* + * First Round: using the given function, the context and a constant + * the next context is computed. Because the algorithms processing + * unit is a 32-bit word and it is determined to work on words in + * little endian byte order we perhaps have to change the byte order + * before the computation. To reduce the work for the next steps we + * store the swapped words in the array CORRECT_WORDS. -- Modified to + * fix the handling of unaligned buffer spaces - Gray 7/97 + */ +#define OP1(a, b, c, d, b_p, c_p, s, T) \ + do { \ + memcpy(c_p, b_p, sizeof(md5_uint32)); \ + *c_p = SWAP(*c_p); \ + a += FF (b, c, d) + *c_p + T; \ + a = CYCLIC (a, s); \ + a += b; \ + b_p = (char *)b_p + sizeof(md5_uint32); \ + c_p++; \ + } while (0) + +/* + * Second to Fourth Round: we have the possibly swapped words in + * CORRECT_WORDS. Redefine the macro to take an additional first + * argument specifying the function to use. + */ +#define OP234(FUNC, a, b, c, d, k, s, T) \ + do { \ + a += FUNC (b, c, d) + k + T; \ + a = CYCLIC (a, s); \ + a += b; \ + } while (0) + +#endif /* ! __MD5_LOC_H__ */ diff --git a/packages/rpm/doxygen.spec b/packages/rpm/doxygen.spec index 04569f7..ce08c50 100644 --- a/packages/rpm/doxygen.spec +++ b/packages/rpm/doxygen.spec @@ -1,6 +1,6 @@ Summary: A documentation system for C/C++. Name: doxygen -Version: 1.3.4_20031019 +Version: 1.3.4_20031026 Release: 1 Epoch: 1 Source0: ftp://ftp.stack.nl/pub/users/dimitri/%{name}-%{version}.src.tar.gz diff --git a/src/dot.cpp b/src/dot.cpp index 79c1320..1b506b1 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -31,6 +31,7 @@ #include #include #include +#include //-------------------------------------------------------------------- @@ -1382,7 +1383,86 @@ void writeDotGraph(DotNode *root, } } -static void findMaximalDotGraph(DotNode *root, +/*! Computes a 16 byte md5 checksum for a given dot graph. + * The md5 checksum is returned as a 32 character ASCII string. + */ +QCString computeMd5Signature(DotNode *root, + DotNode::GraphType gt, + GraphOutputFormat format, + bool lrRank, + bool renderParents, + int distance, + bool backArrows + ) +{ + //printf("computeMd5Signature\n"); + QString buf; + QTextStream md5stream(&buf,IO_WriteOnly); + if (lrRank) + { + md5stream << "rankdir=LR;" << endl; + } + root->clearWriteFlag(); + root->write(md5stream,gt,format,gt!=DotNode::CallGraph,TRUE,distance,backArrows); + if (renderParents && root->m_parents) + { + QListIterator dnli(*root->m_parents); + DotNode *pn; + for (dnli.toFirst();(pn=dnli.current());++dnli) + { + if (pn->m_distance<=distance) + { + root->writeArrow(md5stream, + gt, + format, + pn, + pn->m_edgeInfo->at(pn->m_children->findRef(root)), + FALSE, + backArrows + ); + } + pn->write(md5stream,gt,format,TRUE,FALSE,distance,backArrows); + } + } + char md5_sig[16]; + QCString sigStr(33); + md5_buffer(buf.ascii(),buf.length(),md5_sig); + md5_sig_to_string(md5_sig,sigStr.data(),33); + //printf("md5: %s | file: %s\n",sigStr,baseName.data()); + return sigStr; +} + +/*! Checks if a file "baseName".md5 exists. If so the contents + * are compared with \a md5. If equal FALSE is returned. If the .md5 + * file does not exist or its contents are not equal to \a md5, + * a new .md5 is generated with the \a md5 string as contents. + */ +static bool checkAndUpdateMd5Signature(const QCString &baseName,const QCString &md5) +{ + QFile f(baseName+".md5"); + if (f.open(IO_ReadOnly)) + { + // read checksum + QCString md5stored(33); + int bytesRead=f.readBlock(md5stored.data(),32); + // compare checksum + if (bytesRead==32 && md5==md5stored) + { + // bail out if equal + return FALSE; + } + } + f.close(); + // create checksum file + if (f.open(IO_WriteOnly)) + { + f.writeBlock(md5.data(),32); + f.close(); + } + return TRUE; +} + +static bool findMaximalDotGraph(DotNode *root, int maxDist, const QCString &baseName, QDir &thisDir, @@ -1402,6 +1482,10 @@ static void findMaximalDotGraph(DotNode *root, int maxDotGraphHeight = Config_getInt("MAX_DOT_GRAPH_HEIGHT"); int lastFit=minDistance; + QCString md5 = computeMd5Signature(root,gt,format,lrRank, + renderParents,maxDistance,backArrows); + if (!checkAndUpdateMd5Signature(baseName,md5)) return FALSE; + // binary search for the maximal inheritance depth that fits in a reasonable // sized image (dimensions: Config_getInt("MAX_DOT_GRAPH_WIDTH"), Config_getInt("MAX_DOT_GRAPH_HEIGHT")) while (minDistance<=maxDistance) @@ -1417,7 +1501,7 @@ static void findMaximalDotGraph(DotNode *root, if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) { err("Problems running dot. Check your installation!\n"); - return; + return FALSE; } // extract bounding box from the result @@ -1461,6 +1545,7 @@ static void findMaximalDotGraph(DotNode *root, lastFit, backArrows ); + return TRUE; } QCString DotClassGraph::diskName() const @@ -1520,105 +1605,108 @@ QCString DotClassGraph::writeGraph(QTextStream &out, } baseName = convertNameToFile(diskName()); - findMaximalDotGraph(m_startNode,QMIN(m_recDepth,m_maxDistance),baseName, - thisDir,m_graphType,format,!isTBRank,m_graphType==DotNode::Inheritance); - if (format==BITMAP) // run dot to create a bitmap image + if (findMaximalDotGraph(m_startNode,QMIN(m_recDepth,m_maxDistance),baseName, + thisDir,m_graphType,format,!isTBRank,m_graphType==DotNode::Inheritance)) { - QCString dotArgs(maxCmdLine); - QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT"); - QCString imgName = baseName+"."+imgExt; - dotArgs.sprintf("-T%s \"%s.dot\" -o \"%s\"", - imgExt.data(),baseName.data(),imgName.data()); - if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) - { - err("Error: Problems running dot. Check your installation!\n"); - QDir::setCurrent(oldDir); - return baseName; - } - checkDotResult(imgName); - if (generateImageMap) + + if (format==BITMAP) // run dot to create a bitmap image { - // run dot again to create an image map - dotArgs.sprintf("-Timap \"%s.dot\" -o \"%s.map\"",baseName.data(),baseName.data()); + QCString dotArgs(maxCmdLine); + QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT"); + QCString imgName = baseName+"."+imgExt; + dotArgs.sprintf("-T%s \"%s.dot\" -o \"%s\"", + imgExt.data(),baseName.data(),imgName.data()); if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) { err("Error: Problems running dot. Check your installation!\n"); QDir::setCurrent(oldDir); return baseName; } - QCString mapLabel = convertNameToFile(m_startNode->m_label+"_"+mapName); - out << "

m_label+"_"+mapName); + out << "

\"";
" << endl; + QString tmpstr; + QTextOStream tmpout(&tmpstr); + convertMapFile(tmpout,baseName+".map"); + if (!tmpstr.isEmpty()) + { + out << "" << endl; + out << tmpstr; + out << "" << endl; + } + thisDir.remove(baseName+".map"); + } + } + else if (format==EPS) // run dot to create a .eps image + { + QCString dotArgs(maxCmdLine); + dotArgs.sprintf("-Tps \"%s.dot\" -o \"%s.eps\"",baseName.data(),baseName.data()); + if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) { - case DotNode::Collaboration: - out << "Collaboration graph"; - break; - //case Interface: - // out << "Interface dependency graph"; - // break; - case DotNode::Inheritance: - out << "Inheritance graph"; - break; - default: - ASSERT(0); - break; + err("Error: Problems running dot. Check your installation!\n"); + QDir::setCurrent(oldDir); + return baseName; } - out << "\">
" << endl; - QString tmpstr; - QTextOStream tmpout(&tmpstr); - convertMapFile(tmpout,baseName+".map"); - if (!tmpstr.isEmpty()) + int width,height; + if (!readBoundingBoxEPS(baseName+".eps",&width,&height)) { - out << "" << endl; - out << tmpstr; - out << "" << endl; + err("Error: Could not extract bounding box from .eps!\n"); + QDir::setCurrent(oldDir); + return baseName; } - thisDir.remove(baseName+".map"); - } - } - else if (format==EPS) // run dot to create a .eps image - { - QCString dotArgs(maxCmdLine); - dotArgs.sprintf("-Tps \"%s.dot\" -o \"%s.eps\"",baseName.data(),baseName.data()); - if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) - { - err("Error: Problems running dot. Check your installation!\n"); - QDir::setCurrent(oldDir); - return baseName; - } - int width,height; - if (!readBoundingBoxEPS(baseName+".eps",&width,&height)) - { - err("Error: Could not extract bounding box from .eps!\n"); - QDir::setCurrent(oldDir); - return baseName; - } - if (Config_getBool("USE_PDFLATEX")) - { - QCString epstopdfArgs(maxCmdLine); - epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"", - baseName.data(),baseName.data()); - if (iSystem("epstopdf",epstopdfArgs,TRUE)!=0) + if (Config_getBool("USE_PDFLATEX")) { - err("Error: Problems running epstopdf. Check your TeX installation!\n"); - QDir::setCurrent(oldDir); - return baseName; + QCString epstopdfArgs(maxCmdLine); + epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"", + baseName.data(),baseName.data()); + if (iSystem("epstopdf",epstopdfArgs,TRUE)!=0) + { + err("Error: Problems running epstopdf. Check your TeX installation!\n"); + QDir::setCurrent(oldDir); + return baseName; + } } + int maxWidth = 420; /* approx. page width in points */ + + out << "\\begin{figure}[H]\n" + "\\begin{center}\n" + "\\leavevmode\n" + "\\includegraphics[width=" << QMIN(width/2,maxWidth) + << "pt]{" << baseName << "}\n" + "\\end{center}\n" + "\\end{figure}\n"; } - int maxWidth = 420; /* approx. page width in points */ - - out << "\\begin{figure}[H]\n" - "\\begin{center}\n" - "\\leavevmode\n" - "\\includegraphics[width=" << QMIN(width/2,maxWidth) - << "pt]{" << baseName << "}\n" - "\\end{center}\n" - "\\end{figure}\n"; + if (Config_getBool("DOT_CLEANUP")) thisDir.remove(baseName+".dot"); } - if (Config_getBool("DOT_CLEANUP")) thisDir.remove(baseName+".dot"); QDir::setCurrent(oldDir); return baseName; @@ -1763,101 +1851,103 @@ QCString DotInclDepGraph::writeGraph(QTextStream &out, QCString mapName=m_startNode->m_label.copy(); if (m_inverse) mapName+="dep"; - findMaximalDotGraph(m_startNode,QMIN(m_recDepth,m_maxDistance), + if (findMaximalDotGraph(m_startNode,QMIN(m_recDepth,m_maxDistance), baseName,thisDir,DotNode::Dependency,format, - FALSE,FALSE,!m_inverse); - - if (format==BITMAP) + FALSE,FALSE,!m_inverse) + ) { - // run dot to create a bitmap image - QCString dotArgs(maxCmdLine); - QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT"); - QCString imgName=baseName+"."+imgExt; - dotArgs.sprintf("-T%s \"%s.dot\" -o \"%s\"", - imgExt.data(),baseName.data(),imgName.data()); - if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) - { - err("Problems running dot. Check your installation!\n"); - QDir::setCurrent(oldDir); - return baseName; - } - checkDotResult(imgName); - - if (generateImageMap) + if (format==BITMAP) { - // run dot again to create an image map - dotArgs.sprintf("-Timap \"%s.dot\" -o \"%s.map\"", - baseName.data(),baseName.data()); + // run dot to create a bitmap image + QCString dotArgs(maxCmdLine); + QCString imgExt = Config_getEnum("DOT_IMAGE_FORMAT"); + QCString imgName=baseName+"."+imgExt; + dotArgs.sprintf("-T%s \"%s.dot\" -o \"%s\"", + imgExt.data(),baseName.data(),imgName.data()); if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) { err("Problems running dot. Check your installation!\n"); QDir::setCurrent(oldDir); return baseName; } + checkDotResult(imgName); - out << "

\"";"; - out << "
" << endl; - QString tmpstr; - QTextOStream tmpout(&tmpstr); - convertMapFile(tmpout,baseName+".map"); - if (!tmpstr.isEmpty()) - { - out << "" << endl; - out << tmpstr; - out << "" << endl; + if (m_inverse) out << "Included by dependency graph"; else out << "Include dependency graph"; + out << "\">"; + out << "
" << endl; + QString tmpstr; + QTextOStream tmpout(&tmpstr); + convertMapFile(tmpout,baseName+".map"); + if (!tmpstr.isEmpty()) + { + out << "" << endl; + out << tmpstr; + out << "" << endl; + } + thisDir.remove(baseName+".map"); } - thisDir.remove(baseName+".map"); } - } - else if (format==EPS) - { - // run dot to create a .eps image - QCString dotArgs(maxCmdLine); - dotArgs.sprintf("-Tps \"%s.dot\" -o \"%s.eps\"", - baseName.data(),baseName.data()); - if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) + else if (format==EPS) { - err("Problems running dot. Check your installation!\n"); - QDir::setCurrent(oldDir); - return baseName; - } - int width,height; - if (!readBoundingBoxEPS(baseName+".eps",&width,&height)) - { - err("Error: Could not extract bounding box from .eps!\n"); - QDir::setCurrent(oldDir); - return baseName; - } - if (Config_getBool("USE_PDFLATEX")) - { - QCString epstopdfArgs(maxCmdLine); - epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"", - baseName.data(),baseName.data()); - if (iSystem("epstopdf",epstopdfArgs,TRUE)!=0) + // run dot to create a .eps image + QCString dotArgs(maxCmdLine); + dotArgs.sprintf("-Tps \"%s.dot\" -o \"%s.eps\"", + baseName.data(),baseName.data()); + if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) { - err("Error: Problems running epstopdf. Check your TeX installation!\n"); - QDir::setCurrent(oldDir); - return baseName; + err("Problems running dot. Check your installation!\n"); + QDir::setCurrent(oldDir); + return baseName; + } + int width,height; + if (!readBoundingBoxEPS(baseName+".eps",&width,&height)) + { + err("Error: Could not extract bounding box from .eps!\n"); + QDir::setCurrent(oldDir); + return baseName; + } + if (Config_getBool("USE_PDFLATEX")) + { + QCString epstopdfArgs(maxCmdLine); + epstopdfArgs.sprintf("\"%s.eps\" --outfile=\"%s.pdf\"", + baseName.data(),baseName.data()); + if (iSystem("epstopdf",epstopdfArgs,TRUE)!=0) + { + err("Error: Problems running epstopdf. Check your TeX installation!\n"); + QDir::setCurrent(oldDir); + return baseName; + } } + int maxWidth = 420; /* approx. page width in points */ + + out << "\\begin{figure}[H]\n" + "\\begin{center}\n" + "\\leavevmode\n" + //"\\setlength{\\epsfxsize}{" << QMIN(width/2,maxWidth) << "pt}\n" + //"\\epsfbox{" << baseName << ".eps}\n" + "\\includegraphics[width=" << QMIN(width/2,maxWidth) + << "pt]{" << baseName << "}\n" + "\\end{center}\n" + "\\end{figure}\n"; } - int maxWidth = 420; /* approx. page width in points */ - - out << "\\begin{figure}[H]\n" - "\\begin{center}\n" - "\\leavevmode\n" - //"\\setlength{\\epsfxsize}{" << QMIN(width/2,maxWidth) << "pt}\n" - //"\\epsfbox{" << baseName << ".eps}\n" - "\\includegraphics[width=" << QMIN(width/2,maxWidth) - << "pt]{" << baseName << "}\n" - "\\end{center}\n" - "\\end{figure}\n"; - } - if (Config_getBool("DOT_CLEANUP")) thisDir.remove(baseName+".dot"); + if (Config_getBool("DOT_CLEANUP")) thisDir.remove(baseName+".dot"); + } QDir::setCurrent(oldDir); return baseName; diff --git a/src/dot.h b/src/dot.h index 1723e36..6f89200 100644 --- a/src/dot.h +++ b/src/dot.h @@ -99,14 +99,16 @@ class DotNode friend class DotNodeList; friend class DotCallGraph; friend void writeDotGraph( - DotNode *root, - GraphType gt, - GraphOutputFormat f, - const QCString &baseName, - bool lrRank, - bool renderParents, - int distance, - bool backArrow + DotNode *root, GraphType gt, + GraphOutputFormat f, const QCString &baseName, + bool lrRank, bool renderParents, + int distance, bool backArrows + ); + friend QCString computeMd5Signature( + DotNode *root, GraphType gt, + GraphOutputFormat f, + bool lrRank, bool renderParents, + int distance, bool backArrows ); }; diff --git a/src/doxygen.pro.in b/src/doxygen.pro.in index d397106..8469a12 100644 --- a/src/doxygen.pro.in +++ b/src/doxygen.pro.in @@ -18,18 +18,18 @@ TEMPLATE = app.t CONFIG = console warn_on $extraopts HEADERS = doxygen.h SOURCES = main.cpp -unix:LIBS += -L../lib -ldoxygen -ldoxycfg -lqtools -lpng +unix:LIBS += -L../lib -ldoxygen -ldoxycfg -lqtools -lpng -lmd5 win32:INCLUDEPATH += . -win32-mingw:LIBS += -L../lib -ldoxygen -ldoxycfg -lqtools -lpng -win32-msvc:LIBS += qtools.lib png.lib doxygen.lib doxycfg.lib shell32.lib +win32-mingw:LIBS += -L../lib -ldoxygen -ldoxycfg -lqtools -lpng -lmd5 +win32-msvc:LIBS += qtools.lib png.lib md5.lib doxygen.lib doxycfg.lib shell32.lib win32-msvc:TMAKE_LFLAGS += /LIBPATH:..\lib -win32-borland:LIBS += qtools.lib png.lib doxygen.lib doxycfg.lib shell32.lib +win32-borland:LIBS += qtools.lib png.lib md5.lib doxygen.lib doxycfg.lib shell32.lib win32-borland:TMAKE_LFLAGS += -L..\lib -L$(BCB)\lib\psdk win32:TMAKE_CXXFLAGS += -DQT_NODLL -win32-g++:LIBS = -L../lib -ldoxygen -ldoxycfg -lqtools -lpng +win32-g++:LIBS = -L../lib -ldoxygen -ldoxycfg -lqtools -lpng -lmd5 win32-g++:TMAKE_CXXFLAGS += -fno-exceptions -fno-rtti -INCLUDEPATH += ../qtools ../libpng . -win32-g++:INCLUDEPATH -= ../libpng +INCLUDEPATH += ../qtools ../libpng ../libmd5 . +#win32-g++:INCLUDEPATH -= ../libpng DESTDIR = ../bin TARGET = doxygen unix:TARGETDEPS = ../lib/libdoxygen.a ../lib/libdoxycfg.a diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp index 99bb708..3a260a2 100644 --- a/src/htmlgen.cpp +++ b/src/htmlgen.cpp @@ -1412,7 +1412,7 @@ void HtmlGenerator::writeSearchPage() writeDefaultQuickLinks(t,TRUE,HLI_Search); } - t << "trSearchResultsTitle() << "\";\n"; diff --git a/src/index.cpp b/src/index.cpp index 766bd80..831512b 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -1011,11 +1011,11 @@ void writeFileIndex(OutputList &ol) ol.endBold(); if (hasHtmlHelp) { - htmlHelp->addContentsItem(FALSE,fd->name(),0); + htmlHelp->addContentsItem(FALSE,fullName,0); } if (hasFtvHelp) { - ftvHelp->addContentsItem(FALSE,0,0,0,fd->name()); + ftvHelp->addContentsItem(FALSE,0,0,0,fullName); } } if (src) diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index 1a6c889..f4ff312 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -249,12 +249,12 @@ void LatexDocVisitor::visit(DocVerbatim *s) case DocVerbatim::Code: m_t << "\n\n\\footnotesize\\begin{verbatim}"; parseCode(m_ci,s->context(),s->text().latin1(),s->isExample(),s->exampleFile()); - m_t << "\\end{verbatim}\\normalsize" << endl; + m_t << "\\end{verbatim}\n\\normalsize" << endl; break; case DocVerbatim::Verbatim: m_t << "\n\n\\footnotesize\\begin{verbatim}"; m_t << s->text(); - m_t << "\\end{verbatim}\\normalsize" << endl; + m_t << "\\end{verbatim}\n\\normalsize" << endl; break; case DocVerbatim::HtmlOnly: case DocVerbatim::XmlOnly: @@ -310,7 +310,7 @@ void LatexDocVisitor::visit(DocInclude *inc) case DocInclude::Include: m_t << "\n\n\\footnotesize\\begin{verbatim}"; parseCode(m_ci,inc->context(),inc->text().latin1(),inc->isExample(),inc->exampleFile()); - m_t << "\\end{verbatim}\\normalsize" << endl; + m_t << "\\end{verbatim}\n\\normalsize" << endl; break; case DocInclude::DontInclude: break; @@ -319,7 +319,7 @@ void LatexDocVisitor::visit(DocInclude *inc) case DocInclude::VerbInclude: m_t << "\n\n\\footnotesize\\begin{verbatim}"; m_t << inc->text(); - m_t << "\\end{verbatim}\\normalsize" << endl; + m_t << "\\end{verbatim}\n\\normalsize" << endl; break; } } @@ -344,7 +344,7 @@ void LatexDocVisitor::visit(DocIncOperator *op) if (op->isLast()) { popEnabled(); - if (!m_hide) m_t << "\\end{verbatim}\\normalsize" << endl; + if (!m_hide) m_t << "\\end{verbatim}\n\\normalsize" << endl; } else { diff --git a/src/libdoxygen.pro.in b/src/libdoxygen.pro.in index 630a39e..53b3341 100644 --- a/src/libdoxygen.pro.in +++ b/src/libdoxygen.pro.in @@ -186,6 +186,7 @@ win32-msvc:TMAKE_CXXFLAGS += -Zm200 win32-g++:TMAKE_CXXFLAGS += -fno-exceptions -fno-rtti INCLUDEPATH += ../qtools INCLUDEPATH += ../libpng +INCLUDEPATH += ../libmd5 win32:INCLUDEPATH += . win32-g++:INCLUDEPATH = ../qtools /usr/include/libpng12 DESTDIR = ../lib diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp index f7f8c84..648d3b7 100644 --- a/src/mandocvisitor.cpp +++ b/src/mandocvisitor.cpp @@ -436,6 +436,7 @@ void ManDocVisitor::visitPre(DocSimpleList *) { if (m_hide) return; m_indent+=2; + m_t << ".PD 0" << endl; } void ManDocVisitor::visitPost(DocSimpleList *) @@ -482,6 +483,7 @@ void ManDocVisitor::visitPre(DocHtmlList *) { if (m_hide) return; m_indent+=2; + m_t << ".PD 0" << endl; } void ManDocVisitor::visitPost(DocHtmlList *) diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index 36521ca..4ef5e49 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -1221,8 +1221,9 @@ void RTFDocVisitor::writeDotFile(const QString &fileName) m_t << "{" << endl; m_t << rtf_Style_Reset << endl; m_t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE "; - m_t << outDir << "\\" << baseName; + m_t << baseName << "." << Config_getEnum("DOT_IMAGE_FORMAT"); m_t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl; m_t << "}" << endl; } + diff --git a/src/scanner.l b/src/scanner.l index ae63c72..d70ad39 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -159,6 +159,9 @@ static QCString xrefItemTitle; static QCString xrefListTitle; static QCString g_skipBlockName; +static QCString oldStyleArgType; +static QCString docBackup; +static QCString briefBackup; //----------------------------------------------------------------------------- @@ -475,6 +478,58 @@ static void prependScope() } } +/*! Returns TRUE iff the current entry could be a K&R style C function */ +static bool checkForKnRstyleC() +{ + if (((QCString)yyFileName).right(2)!=".c") return FALSE; // must be a C file + if (!current->argList) return FALSE; + ArgumentListIterator ali(*current->argList); + Argument *a; + for (ali.toFirst();(a=ali.current());++ali) + { + // in K&R style argument do not have a type, but doxygen expects a type + // so it will think the argument has no name + if (a->type.isEmpty() || !a->name.isEmpty()) return FALSE; + } + return TRUE; +} + +/*! Update the argument \a name with additional \a type info. For K&R style + * function the type is found \e after the argument list, so this routine + * in needed to fix up. + */ +void addKnRArgInfo(const QCString &type,const QCString &name, + const QCString &brief,const QCString &docs) +{ + if (current->argList==0) return; + ArgumentListIterator ali(*current->argList); + Argument *a; + for (ali.toFirst();(a=ali.current());++ali) + { + if (a->type==name) + { + a->type=type.stripWhiteSpace(); + if (a->type.left(9)=="register ") // strip keyword + { + a->type=a->type.mid(9); + } + a->name=name.stripWhiteSpace(); + if (!brief.isEmpty() && !docs.isEmpty()) + { + a->docs=brief+"\n\n"+docs; + } + else if (!brief.isEmpty()) + { + a->docs=brief; + } + else + { + a->docs=docs; + } + } + } +} + /* ----------------------------------------------------------------- */ #undef YY_INPUT #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size); @@ -662,6 +717,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] %x PreLineCtrl %x DefinePHP %x DefinePHPEnd +%x OldStyleArgs %% @@ -1510,7 +1566,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] [*&]+ { current->name += yytext ; addType( current ); } -";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { +";"{BN}*("/**"|"//!"|"/*!"|"///")"<" { lineCount(); if (current->bodyLine==-1) current->bodyLine=yyLineNr; @@ -1540,7 +1596,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] BEGIN(AfterDoc); } } -","{BN}*("/**"|"//!"|"/*!"|"///")"<" { +","{BN}*("/**"|"//!"|"/*!"|"///")"<" { lineCount(); lastAfterDocContext = YY_START; afterDocTerminator = ','; @@ -1568,7 +1624,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] BEGIN(AfterDoc); } } -{BN}*("/**"|"//!"|"/*!"|"///")"<" { +{BN}*("/**"|"//!"|"/*!"|"///")"<" { lineCount(); lastAfterDocContext = YY_START; if (YY_START==DefineEnd) @@ -2351,6 +2407,15 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] *copyArgString+=*yytext; fullArgString+=*yytext; stringToArgumentList(fullArgString,current->argList); + + /* remember the current documentation block, since + we could overwrite it with the documentation of + a function argument, which we then have to correct later + on + */ + docBackup = current->doc.copy(); + briefBackup = current->brief.copy(); + BEGIN( currentArgumentContext ); } /* a special comment */ @@ -2536,7 +2601,9 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] } */ [{:;,] { - if ( strcmp(yytext,";")==0 && insidePHP && current->type.left(8) != "function" ) + if ( strcmp(yytext,";")==0 && + insidePHP && + current->type.left(8) != "function" ) { current->reset(); initEntry(); @@ -2547,17 +2614,17 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] unput(*yytext); BEGIN( Function ); } } -{BN}*"const"{BN}* { +{BN}*"const"{BN}* { // const member function lineCount() ; current->args += " const "; current->argList->constSpecifier=TRUE; } -{BN}*"volatile"{BN}* { +{BN}*"volatile"{BN}* { // volatile member function lineCount() ; current->args += " volatile "; current->argList->volatileSpecifier=TRUE; } -{BN}*"="{BN}*"0"{BN}* { +{BN}*"="{BN}*"0"{BN}* { // pure virtual member function lineCount() ; current->args += " = 0"; current->virt = Pure; @@ -2576,6 +2643,82 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] lastCPPContext = YY_START; BEGIN(SkipCPP); } +"=" { // typically a initialized function pointer + current->args += *yytext; + } +{ID} { // typically a K&R style C function + if (checkForKnRstyleC()) + { + fprintf(stderr,"===> got a K&R style function\n"); + current->args = yytext; + oldStyleArgType.resize(0); + BEGIN(OldStyleArgs); + } + else + { + current->args += yytext; + } + } +[,;] { + QCString oldStyleArgPtr; + QCString oldStyleArgName; + if (oldStyleArgType.isEmpty()) + { + int l=current->args.length(),i=l-1,j; + char c; + while (i>=0 && isId(current->args.at(i))) i--; + j=i+1; + while (i>=0 && ((c=current->args.at(i))=='*' || isspace(c))) i--; + i++; + if (i!=l) + { + oldStyleArgType=current->args.left(i); + oldStyleArgPtr=current->args.mid(i,j-i); + oldStyleArgName=current->args.mid(j).stripWhiteSpace(); + } + else + { + oldStyleArgName=current->args.copy().stripWhiteSpace(); + } + } + else + { + int l=current->args.length(),j=0; + char c; + while (jargs.at(j))=='*' || isspace(c))) j++; + if (j>0) + { + oldStyleArgPtr=current->args.left(j); + oldStyleArgName=current->args.mid(j).stripWhiteSpace(); + } + else + { + oldStyleArgName=current->args.copy().stripWhiteSpace(); + } + } + fprintf(stderr,"type=%s ptr=%s name=%s\n",oldStyleArgType.data(),oldStyleArgPtr.data(),oldStyleArgName.data()); + QCString doc,brief; + if (current->doc!=docBackup) + { + doc=current->doc.copy(); + current->doc=docBackup; + } + if (current->brief!=briefBackup) + { + brief=current->brief.copy(); + current->brief=briefBackup; + } + addKnRArgInfo(oldStyleArgType+oldStyleArgPtr,oldStyleArgName,brief,doc); + current->args.resize(0); + if (*yytext==';') oldStyleArgType.resize(0); + } +{ID} { current->args += yytext; } +"{" { + current->args = argListToString(current->argList); + unput('{'); + BEGIN(FuncQual); + } +. { current->args += *yytext; } . { current->args += *yytext; } {BN}*"try"{BN}+ { /* try-function-block */ insideTryBlock=TRUE; @@ -3140,7 +3283,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] } . { current->program += *yytext ; } -("//"{B}*)?"/*!" { +("//"{B}*)?"/*!" { //printf("Start doc block at %d\n",yyLineNr); removeSlashes=(yytext[1]=='/'); tmpDocType=-1; @@ -3161,7 +3304,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] } BEGIN( Doc ); } -("//"{B}*)?"/**"/[^/*] { +("//"{B}*)?"/**"/[^/*] { removeSlashes=(yytext[1]=='/'); lastDocContext = YY_START; //printf("Found comment block at %s:%d\n",yyFileName,yyLineNr); @@ -3212,7 +3355,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] } } } -"//!" { +"//!" { if (YY_START!=SkipCurly) { current->brief.resize(0); @@ -3231,7 +3374,7 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] } BEGIN( LineDoc ); } -"///"/[^/] { +"///"/[^/] { if (YY_START!=SkipCurly) { current->brief.resize(0); @@ -4367,13 +4510,15 @@ PHPKW ("require"|"require_once"|"include"|"include_once"|"echo")[^a-zA-Z0-9_;] } } "*/" { - unput('/');unput('*'); - BEGIN( lastIfContext ); + BEGIN( SkipSection ); + } +"/*!" { + BEGIN( SkipSection ); } \n { yyLineNr++; } -"//"|"*/" +"//"|"*/" {CMD}"elseif"/[^a-z_A-Z0-9] { // previous section enabled => skip now depthIf=1; diff --git a/src/search.php b/src/search.php index 29bbc7a..7075ea3 100644 --- a/src/search.php +++ b/src/search.php @@ -193,6 +193,10 @@ function filter_results($docs,&$requiredWords,&$forbiddenWords) function compare_rank($a,$b) { + if ($a["rank"] == $b["rank"]) + { + return 0; + } return ($a["rank"]>$b["rank"]) ? -1 : 1; } diff --git a/src/search_php.h b/src/search_php.h index 7f24842..4213b19 100644 --- a/src/search_php.h +++ b/src/search_php.h @@ -193,6 +193,10 @@ "\n" "function compare_rank($a,$b)\n" "{\n" +" if ($a[\"rank\"] == $b[\"rank\"]) \n" +" {\n" +" return 0;\n" +" }\n" " return ($a[\"rank\"]>$b[\"rank\"]) ? -1 : 1; \n" "}\n" "\n" diff --git a/src/translator_kr.h b/src/translator_kr.h index bdf1e5e..f94dcb6 100644 --- a/src/translator_kr.h +++ b/src/translator_kr.h @@ -26,7 +26,7 @@ #ifndef TRANSLATOR_KR_H #define TRANSLATOR_KR_H -class TranslatorKorean : public TranslatorAdapter_1_3 +class TranslatorKorean : public Translator { public: -- cgit v0.12