My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Macros | Functions
rtfgen.cpp File Reference
#include <stdlib.h>
#include <qdir.h>
#include <qregexp.h>
#include <qtextstream.h>
#include "rtfgen.h"
#include "config.h"
#include "message.h"
#include "doxygen.h"
#include "util.h"
#include "diagram.h"
#include "language.h"
#include "dot.h"
#include "version.h"
#include "pagedef.h"
#include "rtfstyle.h"
#include "rtfdocvisitor.h"
#include "docparser.h"
#include "dirdef.h"
#include "vhdldocgen.h"
#include "portable.h"
#include "groupdef.h"
#include "classlist.h"
#include "filename.h"
#include "namespacedef.h"

Go to the source code of this file.

Macros

#define DBG_RTF(x)
 

Functions

static QCString dateToRTFDateString ()
 
static QCString makeIndexName (const char *s, int i)
 
bool isLeadBytes (int c)
 
static void encodeForOutput (FTextStream &t, const char *s)
 
static bool preProcessFile (QDir &d, QCString &infName, FTextStream &t, bool bIncludeHeader=TRUE)
 
void testRTFOutput (const char *name)
 

Macro Definition Documentation

#define DBG_RTF (   x)

Definition at line 48 of file rtfgen.cpp.

Referenced by RTFGenerator::beginRTFChapter(), RTFGenerator::beginRTFDocument(), RTFGenerator::beginRTFSection(), RTFGenerator::endCallGraph(), RTFGenerator::endCodeFragment(), RTFGenerator::endConstraintDocs(), RTFGenerator::endConstraintList(), RTFGenerator::endConstraintParam(), RTFGenerator::endConstraintType(), RTFGenerator::endDescForItem(), RTFGenerator::endDescItem(), RTFGenerator::endDescription(), RTFGenerator::endDescTable(), RTFGenerator::endDescTableData(), RTFGenerator::endDescTableTitle(), RTFGenerator::endDirDepGraph(), RTFGenerator::endDotGraph(), RTFGenerator::endDoxyAnchor(), RTFGenerator::endFile(), RTFGenerator::endGroupHeader(), RTFGenerator::endInclDepGraph(), RTFGenerator::endIndexItem(), RTFGenerator::endIndexKey(), RTFGenerator::endIndexList(), RTFGenerator::endIndexListItem(), RTFGenerator::endIndexSection(), RTFGenerator::endIndexValue(), RTFGenerator::endInlineHeader(), RTFGenerator::endInlineMemberDoc(), RTFGenerator::endInlineMemberName(), RTFGenerator::endInlineMemberType(), RTFGenerator::endItemList(), RTFGenerator::endItemListItem(), RTFGenerator::endMemberDescription(), RTFGenerator::endMemberDoc(), RTFGenerator::endMemberDocSimple(), RTFGenerator::endMemberGroup(), RTFGenerator::endMemberGroupDocs(), RTFGenerator::endMemberGroupHeader(), RTFGenerator::endMemberItem(), RTFGenerator::endMemberList(), RTFGenerator::endMemberSubtitle(), RTFGenerator::endParagraph(), RTFGenerator::endParameterType(), RTFGenerator::endParamList(), RTFGenerator::endProjectNumber(), RTFGenerator::endSection(), RTFGenerator::endSimpleSect(), RTFGenerator::endTextBlock(), RTFGenerator::endTitleHead(), RTFGenerator::exceptionEntry(), RTFGenerator::lastIndexPage(), RTFGenerator::lineBreak(), RTFGenerator::newParagraph(), preProcessFile(), RTFGenerator::rtfwriteRuler_doubleline(), RTFGenerator::rtfwriteRuler_emboss(), RTFGenerator::rtfwriteRuler_thick(), RTFGenerator::rtfwriteRuler_thin(), RTFGenerator::startCallGraph(), RTFGenerator::startClassDiagram(), RTFGenerator::startCodeFragment(), RTFGenerator::startConstraintDocs(), RTFGenerator::startConstraintList(), RTFGenerator::startConstraintParam(), RTFGenerator::startConstraintType(), RTFGenerator::startDescForItem(), RTFGenerator::startDescItem(), RTFGenerator::startDescList(), RTFGenerator::startDescription(), RTFGenerator::startDescTable(), RTFGenerator::startDescTableData(), RTFGenerator::startDescTableTitle(), RTFGenerator::startDirDepGraph(), RTFGenerator::startDotGraph(), RTFGenerator::startDoxyAnchor(), RTFGenerator::startGroupHeader(), RTFGenerator::startInclDepGraph(), RTFGenerator::startIndent(), RTFGenerator::startIndexItem(), RTFGenerator::startIndexKey(), RTFGenerator::startIndexList(), RTFGenerator::startIndexListItem(), RTFGenerator::startIndexSection(), RTFGenerator::startIndexValue(), RTFGenerator::startInlineHeader(), RTFGenerator::startInlineMemberDoc(), RTFGenerator::startInlineMemberName(), RTFGenerator::startInlineMemberType(), RTFGenerator::startItemList(), RTFGenerator::startItemListItem(), RTFGenerator::startMemberDescription(), RTFGenerator::startMemberDoc(), RTFGenerator::startMemberDocSimple(), RTFGenerator::startMemberGroup(), RTFGenerator::startMemberGroupDocs(), RTFGenerator::startMemberGroupHeader(), RTFGenerator::startMemberItem(), RTFGenerator::startMemberList(), RTFGenerator::startMemberSubtitle(), RTFGenerator::startParagraph(), RTFGenerator::startParameterType(), RTFGenerator::startParamList(), RTFGenerator::startProjectNumber(), RTFGenerator::startSection(), RTFGenerator::startSimpleSect(), RTFGenerator::startSubsection(), RTFGenerator::startSubsubsection(), RTFGenerator::startTextBlock(), RTFGenerator::startTitle(), RTFGenerator::startTitleHead(), RTFGenerator::writeAnchor(), RTFGenerator::writeEndAnnoItem(), and RTFGenerator::writeStartAnnoItem().

Function Documentation

static QCString dateToRTFDateString ( )
static

Definition at line 50 of file rtfgen.cpp.

Referenced by RTFGenerator::endIndexSection().

{
const QDateTime &d = QDateTime::currentDateTime();
QCString result;
result.sprintf("\\yr%d\\mo%d\\dy%d\\hr%d\\min%d\\sec%d",
d.date().year(), d.date().month(), d.date().day(),
d.time().hour(),d.time().minute(),d.time().second());
return result;
}
static void encodeForOutput ( FTextStream t,
const char *  s 
)
static

Definition at line 2318 of file rtfgen.cpp.

References isLeadBytes(), portable_iconv(), portable_iconv_close(), portable_iconv_open(), theTranslator, and Translator::trRTFansicp().

Referenced by preProcessFile().

{
if (s==0) return;
QCString encoding;
bool converted=FALSE;
int l = qstrlen(s);
static QByteArray enc;
if (l*4>(int)enc.size()) enc.resize(l*4); // worst case
encoding.sprintf("CP%s",theTranslator->trRTFansicp().data());
if (!encoding.isEmpty())
{
// convert from UTF-8 back to the output encoding
void *cd = portable_iconv_open(encoding,"UTF-8");
if (cd!=(void *)(-1))
{
size_t iLeft=l;
size_t oLeft=enc.size();
char *inputPtr = (char*)s;
char *outputPtr = enc.data();
if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
{
enc.resize(enc.size()-(unsigned int)oLeft);
converted=TRUE;
}
}
}
if (!converted) // if we did not convert anything, copy as is.
{
memcpy(enc.data(),s,l);
enc.resize(l);
}
uint i;
bool multiByte = FALSE;
for (i=0;i<enc.size();i++)
{
uchar c = (uchar)enc.at(i);
if (c>=0x80 || multiByte)
{
char esc[10];
sprintf(esc,"\\'%X",c); // escape sequence for SBCS and DBCS(1st&2nd bytes).
t << esc;
if (!multiByte)
{
multiByte = isLeadBytes(c); // It may be DBCS Codepages.
}
else
{
multiByte = FALSE; // end of Double Bytes Character.
}
}
else
{
t << (char)c;
}
}
}
bool isLeadBytes ( int  c)

Definition at line 2286 of file rtfgen.cpp.

References theTranslator, and Translator::trRTFansicp().

Referenced by encodeForOutput().

{
bool result;
QCString codePage = theTranslator->trRTFansicp();
if (codePage == "932") // cp932 (Japanese Shift-JIS)
{
result = (0x81<=c && c<=0x9f) || (0xe0<=c && c<=0xfc);
}
else if (codePage == "936") // cp936 (Simplified Chinese GBK)
{
result = 0x81<=c && c<=0xFE;
}
else if (codePage == "949") // cp949 (Korean)
{
result = 0x81<=c && c<=0xFE;
}
else if (codePage == "950") // cp950 (Traditional Chinese Big5)
{
result = 0x81<=c && c<=0xFE;
}
else // for SBCS Codepages (cp1252,1251 etc...)
{
result = false;
}
return result;
}
static QCString makeIndexName ( const char *  s,
int  i 
)
static
static bool preProcessFile ( QDir &  d,
QCString &  infName,
FTextStream t,
bool  bIncludeHeader = TRUE 
)
static

VERY brittle routine inline RTF's included by other RTF's. it is recursive and ugly.

Definition at line 2383 of file rtfgen.cpp.

References DBG_RTF, encodeForOutput(), endl(), and err().

Referenced by RTFGenerator::preProcessFileInplace().

{
QFile f(infName);
if (!f.open(IO_ReadOnly))
{
err("problems opening rtf file %s for reading\n",infName.data());
return FALSE;
}
const int maxLineLength = 10240;
static QCString lineBuf(maxLineLength);
// scan until find end of header
// this is EXTREEEEEEEMLY brittle. It works on OUR rtf
// files because the first line before the body
// ALWAYS contains "{\comment begin body}"
int len;
for(;;)
{
lineBuf.resize(maxLineLength);
if ((len=f.readLine(lineBuf.rawData(),maxLineLength))==-1)
{
err("read error in %s before end of RTF header!\n",infName.data());
return FALSE;
}
lineBuf.resize(len+1);
if (lineBuf.find("\\comment begin body")!=-1) break;
if (bIncludeHeader) encodeForOutput(t,lineBuf.data());
}
lineBuf.resize(maxLineLength);
while ((len=f.readLine(lineBuf.rawData(),maxLineLength))!=-1)
{
lineBuf.resize(len+1);
int pos;
if ((pos=lineBuf.find("INCLUDETEXT"))!=-1)
{
int startNamePos = lineBuf.find('"',pos)+1;
int endNamePos = lineBuf.find('"',startNamePos);
QCString fileName = lineBuf.mid(startNamePos,endNamePos-startNamePos);
DBG_RTF(t << "{\\comment begin include " << fileName << "}" << endl)
if (!preProcessFile(d,fileName,t,FALSE)) return FALSE;
DBG_RTF(t << "{\\comment end include " << fileName << "}" << endl)
}
else // no INCLUDETEXT on this line
{
// elaborate hoopla to skip the final "}" if we didn't include the
// headers
if (!f.atEnd() || bIncludeHeader)
{
encodeForOutput(t,lineBuf);
}
else // last line of included file
{
// null terminate at the last '}'
//char *str = strrchr(buffer,'}');
int pos = lineBuf.findRev('}');
if (pos != -1)
lineBuf.at(pos) = '\0';
else
err("Strange, the last char was not a '}'\n");
encodeForOutput(t,lineBuf);
}
}
lineBuf.resize(maxLineLength);
}
f.close();
// remove temporary file
d.remove(infName);
return TRUE;
}
void testRTFOutput ( const char *  name)

Tests the integrity of the result by counting brackets.

Definition at line 2561 of file rtfgen.cpp.

References err().

Referenced by RTFGenerator::preProcessFileInplace().

{
int bcount=0;
int line=1;
int c;
QFile f(name);
if (f.open(IO_ReadOnly))
{
while ((c=f.getch())!=-1)
{
if (c=='\\') // escape char
{
c=f.getch();
if (c==-1) break;
}
else if (c=='{') // open bracket
{
bcount++;
}
else if (c=='}') // close bracket
{
bcount--;
if (bcount<0)
{
goto err;
break;
}
}
else if (c=='\n') // newline
{
line++;
}
}
}
if (bcount==0) return; // file is OK.
err("RTF integrity test failed at line %d of %s due to a bracket mismatch.\n"
" Please try to create a small code example that produces this error \n"
" and send that to dimitri@stack.nl.\n",line,name);
}