summaryrefslogtreecommitdiffstats
path: root/unix/dltest/pkga.c
diff options
context:
space:
mode:
authordas <das>2007-08-14 06:32:55 (GMT)
committerdas <das>2007-08-14 06:32:55 (GMT)
commit1d3c3ca5bc5a27b8810c6653a5cdafd895a64c0b (patch)
tree85b24d056d0a9723d0d81dde23cd24241372e6b9 /unix/dltest/pkga.c
parenta789ab33c1944041459d117c719d57c44582b717 (diff)
downloadtcl-1d3c3ca5bc5a27b8810c6653a5cdafd895a64c0b.zip
tcl-1d3c3ca5bc5a27b8810c6653a5cdafd895a64c0b.tar.gz
tcl-1d3c3ca5bc5a27b8810c6653a5cdafd895a64c0b.tar.bz2
* unix/dltest/pkga.c: whitespace & comment cleanup, remove
* unix/dltest/pkgb.c: unused pkgf.c. * unix/dltest/pkgc.c: * unix/dltest/pkge.c: * unix/dltest/pkgf.c (removed): * unix/dltest/pkgua.c: * macosx/Tcl.xcodeproj/project.pbxproj:
Diffstat (limited to 'unix/dltest/pkga.c')
-rw-r--r--unix/dltest/pkga.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/unix/dltest/pkga.c b/unix/dltest/pkga.c
index b282614..d78e611 100644
--- a/unix/dltest/pkga.c
+++ b/unix/dltest/pkga.c
@@ -9,8 +9,9 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: pkga.c,v 1.10 2007/05/29 14:05:53 dgp Exp $
+ * RCS: @(#) $Id: pkga.c,v 1.11 2007/08/14 06:32:55 das Exp $
*/
+
#include "tcl.h"
/*
a> 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494
/******************************************************************************
 *
 * 
 *
 * Copyright (C) 1997-2001 by Dimitri van Heesch.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation under the terms of the GNU General Public License is hereby 
 * granted. No representations are made about the suitability of this software 
 * for any purpose. It is provided "as is" without express or implied warranty.
 * See the GNU General Public License for more details.
 *
 * Documents produced by Doxygen are derivative works derived from the
 * input used in their production; they are not affected by this license.
 *
 */

#include <stdio.h>
#include <qregexp.h>
#include "memberdef.h"
#include "membername.h"
#include "doxygen.h"
#include "util.h"
#include "code.h"
#include "message.h"
#include "htmlhelp.h"
#include "language.h"
#include "outputlist.h"
#include "example.h"
#include "membergroup.h"
#include "doc.h"
#include "groupdef.h"
#include "defargs.h"
//#include "xml.h"

//-----------------------------------------------------------------------------

static QCString addTemplateNames(const QCString &s,const QCString &n,const QCString &t)
{
  QCString result;
  QCString clRealName=n;
  int p=0,i;
  if ((i=clRealName.find('<'))!=-1)
  {
    clRealName=clRealName.left(i); // strip template specialization
  }
  if ((i=clRealName.findRev("::"))!=-1)
  {
    clRealName=clRealName.right(clRealName.length()-i-2);
  }
  while ((i=s.find(clRealName,p))!=-1)
  {
    result+=s.mid(p,i-p);
    uint j=clRealName.length()+i;
    if (s.length()==j || (s.at(j)!='<' && !isId(s.at(j))))
    { // add template names
      //printf("Adding %s+%s\n",clRealName.data(),t.data());
      result+=clRealName+t; 
    }
    else 
    { // template names already present
      //printf("Adding %s\n",clRealName.data());
      result+=clRealName;
    }
    p=i+clRealName.length();
  }
  result+=s.right(s.length()-p);
  //printf("addTemplateNames(%s,%s,%s)=%s\n",s.data(),n.data(),t.data(),result.data());
  return result;
}

static void writeDefArgumentList(OutputList &ol,ClassDef *cd,
                                 const QCString &scopeName,MemberDef *md)
{
  ArgumentList *argList=md->argumentList();
  if (argList==0) return; // member has no function like argument list
  if (!md->isDefine()) ol.docify(" ");
  ol.docify("("); // start argument list
  ol.endMemberDocName();
  Argument *a=argList->first();
  QCString cName;
  if (md->scopeDefTemplateArguments())
  {
    cName=tempArgListToString(md->scopeDefTemplateArguments());
  }
  if (cd)
  {
    cName=cd->name();
    int il=cName.find('<');
    int ir=cName.findRev('>');
    if (il!=-1 && ir!=-1 && ir>il)
    {
      cName=cName.mid(il,ir-il+1);
      //printf("1. cName=%s\n",cName.data());
    }
    else if (cd->templateArguments())
    {
      cName=tempArgListToString(cd->templateArguments()); 
      //printf("2. cName=%s\n",cName.data());
    }
    else // no template specifier
    {
      cName.resize(0);
    }
  }
  //printf("~~~ %s cName=%s\n",md->name().data(),cName.data());

  //if (!md->isDefine()) ol.startParameter(TRUE); else ol.docify(" ");
  ol.startParameter(TRUE); 
  bool first=TRUE;
  while (a)
  {
    QRegExp re(")(");
    int vp;
    if (!a->attrib.isEmpty()) // argument has an IDL attribute
    {
      ol.docify(a->attrib+" ");
    }
    if ((vp=a->type.find(re))!=-1) // argument type is a function pointer
    {
      QCString n=a->type.left(vp);
      if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
      linkifyText(TextGeneratorOLImpl(ol),scopeName,md->name(),n);
    }
    else // non-function pointer type
    {
      QCString n=a->type;
      if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
      linkifyText(TextGeneratorOLImpl(ol),scopeName,md->name(),n);
    }
    if (!a->name.isEmpty()) // argument has a name
    { 
      ol.docify(" ");
      ol.disable(OutputGenerator::Man);
      ol.startEmphasis();
      ol.enable(OutputGenerator::Man);
      ol.docify(a->name);
      ol.disable(OutputGenerator::Man);
      ol.endEmphasis();
      ol.enable(OutputGenerator::Man);
    }
    if (!a->array.isEmpty())
    {
      ol.docify(a->array);
    }
    if (vp!=-1) // write the part of the argument type 
                // that comes after the name
    {
      linkifyText(TextGeneratorOLImpl(ol),scopeName,md->name(),a->type.right(a->type.length()-vp));
    }
    if (!a->defval.isEmpty()) // write the default value
    {
      QCString n=a->defval;
      if (!cName.isEmpty()) n=addTemplateNames(n,cd->name(),cName);
      ol.docify(" = ");
      linkifyText(TextGeneratorOLImpl(ol),scopeName,md->name(),n); 
    }
    a=argList->next();
    if (a) 
    {
      ol.docify(", "); // there are more arguments
      if (!md->isDefine()) 
      {
        ol.endParameter(first);
        ol.startParameter(FALSE);
      }
    }
    first=FALSE;
  }
  ol.pushGeneratorState();
  ol.disableAllBut(OutputGenerator::Html);
  if (!first) ol.writeString("&nbsp;");
  ol.popGeneratorState();
  ol.docify(")"); // end argument list
  if (argList->constSpecifier)
  {
    ol.docify(" const");
  }
  if (argList->volatileSpecifier)
  {
    ol.docify(" volatile");
  }
}

static void writeTemplatePrefix(OutputList &ol,ArgumentList *al,bool br=TRUE)
{
  ol.docify("template<");
  Argument *a=al->first();
  while (a)
  {
    ol.docify(a->type);
    ol.docify(" ");
    ol.docify(a->name);
    if (a->defval.length()!=0)
    {
      ol.docify(" = ");
      ol.docify(a->defval);
    } 
    a=al->next();
    if (a) ol.docify(", ");
  }
  ol.docify("> ");
  if (br)
  {
  //  ol.pushGeneratorState();
  //  ol.disable(OutputGenerator::Man);
  //  ol.disable(OutputGenerator::Latex);
  //  ol.lineBreak();
  //  ol.popGeneratorState();
  }
}

//-----------------------------------------------------------------------------

/*! Creates a new member definition.
 *  Members can be function/variables/enums/etc. inside a class or inside a 
 *  file.
 *
 * \param df File containing the definition of this member.
 * \param dl Line at which the member definition was found.
 * \param t  A string representing the type of the member.
 * \param n  A string representing the name of the member.
 * \param a  A string representing the arguments of the member.
 * \param p  The type of protection of the member, possible values are:
 *           \c Public, \c Protected, \c Private.
 * \param v  The `virtualness' of the member, possible values are:
 *           \c Normal, \c Virtual, \c Pure.
 * \param s  A boolean that is true if the member is static.
 * \param r  A boolean that is true if the member is only related.
 * \param mt The kind of member. See #MemberDef::MemberType for a list of 
 *           all types.
 */

MemberDef::MemberDef(const char *df,int dl,
                     const char *t,const char *na,const char *a,const char *e,
                     Protection p,Specifier v,bool s,bool r,MemberType mt,
                     const ArgumentList *tal,const ArgumentList *al
                    ) : Definition(df,dl,na)
{
  //printf("++++++ MemberDef(%s file=%s,line=%d) ++++++ \n",na,df,dl);
  classDef=0;
  fileDef=0;
  //fileDec=0;
  redefines=0;
  redefinedBy=0;
  nspace=0;
  memDef=0;
  memDec=0;
  group=0;
  grpId=-1;
  exampleList=0;
  exampleDict=0;
  enumFields=0;
  enumScope=0;
  enumDeclList=0;
  scopeTAL=0;
  membTAL=0;
  initLines=0;
  type=t;
  args=a;
  args=removeRedundantWhiteSpace(args);
  if (type.isEmpty()) decl=name()+args; else decl=type+" "+name()+args;
  declLine=0;
  memberGroup=0;
  virt=v;
  prot=p;
  related=r;
  stat=s;
  mtype=mt;
  exception=e;
  eUsed=FALSE;
  proto=FALSE;
  annScope=FALSE;
  memSpec=FALSE;
  annMemb=0;
  annUsed=FALSE;
  annShown=FALSE;
  annEnumType=0;
  indDepth=0;
  section=0;
  explExt=FALSE;
  maxInitLines=Config::instance()->getInt("MAX_INITIALIZER_LINES");
  userInitLines=-1;
  docEnumValues=FALSE;
  // copy function template arguments (if any)
  if (tal)
  {
    tArgList = new ArgumentList;
    tArgList->setAutoDelete(TRUE);
    ArgumentListIterator ali(*tal);
    Argument *a;
    for (;(a=ali.current());++ali)
    {
      tArgList->append(new Argument(*a));
    }
  }
  else
  {
    tArgList=0;
  }
  // copy function arguments (if any)
  if (al)
  {
    argList = new ArgumentList;
    argList->setAutoDelete(TRUE);
    ArgumentListIterator ali(*al);
    Argument *a;
    for (;(a=ali.current());++ali)
    {
      argList->append(new Argument(*a));
    }
    argList->constSpecifier    = al->constSpecifier;
    argList->volatileSpecifier = al->volatileSpecifier;
    argList->pureSpecifier     = al->pureSpecifier;
  }
  else
  {
    argList=0;
  }
}

MemberDef::~MemberDef()
{
  delete redefinedBy;
  delete exampleList;
  delete exampleDict;
  delete enumFields;
  delete argList;
  delete tArgList;
}

void MemberDef::insertReimplementedBy(MemberDef *md)
{
  if (redefinedBy==0) redefinedBy = new MemberList;
  redefinedBy->inSort(md);
}

void MemberDef::insertEnumField(MemberDef *md)
{
  if (enumFields==0) enumFields=new MemberList;
  enumFields->append(md);
}

bool MemberDef::addExample(const char *anchor,const char *nameStr,
                           const char *file)
{
  //printf("%s::addExample(%s,%s,%s)\n",name.data(),anchor,nameStr,file);
  if (exampleDict==0) exampleDict = new ExampleDict;
  if (exampleList==0) exampleList = new ExampleList;
  if (exampleDict->find(nameStr)==0) 
  {
    //printf("Add reference to example %s to member %s\n",nameStr,name.data());
    Example *e=new Example;
    e->anchor=anchor;
    e->name=nameStr;
    e->file=file;
    exampleDict->insert(nameStr,e);
    exampleList->inSort(e); 
    return TRUE;
  }
  return FALSE; 
}

bool MemberDef::hasExamples()
{
  if (exampleList==0) 
    return FALSE;
  else
    return exampleList->count()>0;
}

#if 0
void MemberDef::writeExample(OutputList &ol)
{
  Example *e=exampleList->first();
  while (e)
  {
    ol.writeObjectLink(0,e->file,e->anchor,e->name);
    e=exampleList->next();
    if (e)
    {
      if (exampleList->at()==(int)exampleList->count()-1)
        ol.writeString(" and ");
      else
        ol.writeString(", ");
    }
  }
  ol.writeString(".");
}
#endif

QCString MemberDef::getOutputFileBase() const
{
  if (classDef)
  {
    return classDef->getOutputFileBase();
  }
  else if (fileDef)
  {
    return fileDef->getOutputFileBase();
  }
  //else if (fileDec)
  //{
  //  return fileDec->getOutputFileBase();
  //}
  else if (nspace)
  {
    return nspace->getOutputFileBase();
  }
  warn(defFileName,defLine,
       "Warning: Internal inconsistency: member %s does not belong to any"
       " container!",name().data()
      );
  return "dummy";
}

static void copyArgumentList(const ArgumentList *src,ArgumentList *dst)
{
  ArgumentListIterator tali(*src);
  Argument *a;
  for (;(a=tali.current());++tali)
  {
    dst->append(new Argument(*a));
  }
  dst->constSpecifier    = src->constSpecifier;
  dst->volatileSpecifier = src->volatileSpecifier;
  dst->pureSpecifier     = src->pureSpecifier;
}

void MemberDef::setScopeDefTemplateArguments(ArgumentList *tal)
{
  // copy function arguments (if any)
  if (tal)
  {
    scopeTAL = new ArgumentList;
    scopeTAL->setAutoDelete(TRUE);
    copyArgumentList(tal,scopeTAL);
  }
}

void MemberDef::setMemberDefTemplateArguments(ArgumentList *tal)
{
  // copy function arguments (if any)
  if (tal)
  {
    membTAL = new ArgumentList;
    membTAL->setAutoDelete(TRUE);
    copyArgumentList(tal,membTAL);
  }
}

void MemberDef::writeLink(OutputList &ol,ClassDef *cd,NamespaceDef *nd,
                      FileDef *fd,GroupDef *gd)
{
  Definition *d=0;
  if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else if (gd) d=gd;
  if (d==0) { err("Member %s without group! Please report this bug!\n",name().data()); return; }
  if (group!=0 && gd==0) // forward link to the group
  {
    ol.writeObjectLink(group->getReference(),group->getOutputFileBase(),anchor(),name());
  }
  else // local link
  {
    ol.writeObjectLink(d->getReference(),d->getOutputFileBase(),anchor(),name());
  }
}


void MemberDef::writeDeclaration(OutputList &ol,
               ClassDef *cd,NamespaceDef *nd,FileDef *fd,GroupDef *gd,
               bool inGroup
               )
{
  int i,l;
  bool hasDocs=hasDocumentation();
  //printf("%s MemberDef::writeDeclaration(): hasDocs %d\n",name().data(),hasDocs);
  //if (cd)
  //{
  //  printf("MemberDef: %s in class %s annScope=%d annMemb=%p\n",
  //    name().data(),cd->name().data(),annScope,annMemb);
  //}

  // hide members in anonymous scopes 
  // (they are displayed by there parent placeholder)
  if (annScope) return;
  // hide undocumented members unless overwritten by the configuration
  if (!hasDocs && Config::instance()->getBool("HIDE_UNDOC_MEMBERS")) return;
  // hide members with no detailed desciption and brief descriptions explicitly
  // disabled.
  if (Config::instance()->getBool("HIDE_UNDOC_MEMBERS") && documentation().isEmpty() && 
      !Config::instance()->getBool("BRIEF_MEMBER_DESC") && !Config::instance()->getBool("REPEAT_BRIEF") 
     ) return;
  // hide static file & namespace members unless extract static is on
  if (cd==0 && isStatic() && !Config::instance()->getBool("EXTRACT_STATIC")) return;

  // hide private member that are put into a member group. Non-grouped
  // members are not rendered anyway.
  //printf("md->name()=`%s' Protection=%d\n",name().data(),protection());
  if (inGroup && protection()==Private && !Config::instance()->getBool("EXTRACT_PRIVATE")) return;

  QCString ltype=type.copy();
  // strip `static' keyword from ltype
  if (ltype.left(7)=="static ") ltype=ltype.right(ltype.length()-7);
  // strip `friend' keyword from ltype
  if (ltype.left(7)=="friend ") ltype=ltype.right(ltype.length()-7);
  static QRegExp r("@[0-9]+");
  i=-1;
  if ((ltype.isEmpty() || (i=r.match(ltype,0,&l))==-1) || !enumUsed())
  {
    
    if (!Config::instance()->getString("GENERATE_TAGFILE").isEmpty())
    {
      Doxygen::tagFile << "    <member kind=\"";
      switch (mtype)
      {
        case Define:      Doxygen::tagFile << "define";      break;
        case EnumValue:   Doxygen::tagFile << "enumvalue";   break;
        case Property:    Doxygen::tagFile << "property";    break;
        case Variable:    Doxygen::tagFile << "variable";    break;
        case Typedef:     Doxygen::tagFile << "typedef";     break;
        case Enumeration: Doxygen::tagFile << "enumeration"; break;
        case Function:    Doxygen::tagFile << "function";    break;
        case Signal:      Doxygen::tagFile << "signal";      break;
        case Prototype:   Doxygen::tagFile << "prototype";   break;
        case Friend:      Doxygen::tagFile << "friend";      break;
        case DCOP:        Doxygen::tagFile << "dcop";        break;
        case Slot:        Doxygen::tagFile << "slot";        break;
      }
      if (prot!=Public)
      {
        Doxygen::tagFile << "\" protection=\"";
        if (prot==Protected) Doxygen::tagFile << "public";
        else /* Private */   Doxygen::tagFile << "protected"; 
      }
      if (virt!=Normal)
      {
        Doxygen::tagFile << "\" virtualness=\"";
        if (virt==Virtual) Doxygen::tagFile << "virtual";
        else /* Pure */    Doxygen::tagFile << "pure"; 
      }
      if (isStatic())
      {
        Doxygen::tagFile << "\" static=\"yes";
      }
      Doxygen::tagFile << "\">" << endl;
      Doxygen::tagFile << "      <name>" << convertToXML(name()) << "</name>" << endl;
      Doxygen::tagFile << "      <anchor>" << convertToXML(anchor()) << "</anchor>" << endl;
      Doxygen::tagFile << "      <arglist>" << convertToXML(argsString()) << "</arglist>" << endl;
      writeDocAnchorsToTagFile();
      Doxygen::tagFile << "    </member>" << endl;
    }
      
    Definition *d=0;
    ASSERT (cd!=0 || nd!=0 || fd!=0 || gd!=0); // member should belong to something
    if (cd) d=cd; else if (nd) d=nd; else if (fd) d=fd; else d=gd;
    QCString cname  = d->name();
    QCString cfname = d->getOutputFileBase();

    //int gId = inGroup ? -1 : groupId();
    //MemberGroup *mg = (gId!=prevGroupId && gId!=-1) ? memberGroupDict[gId] : 0;
    //const char *gHeader = 0;
    //const char *gFile = 0;
    //if (mg)
    //{
    //  gHeader=mg->header();
    //  gFile=mg->getOutputFileBase();
    //}
    //
    //if (!inGroup)
    //{
    //  if (prevGroupId==-1 && gId!=-1)
    //  {
    //    ol.memberGroupSpacing(FALSE);
    //    ol.memberGroupSeparator();
    //  }
    //  else if (prevGroupId!=-1 && gId==-1)
    //  {
    //    ol.memberGroupSpacing(TRUE);
    //    ol.memberGroupSeparator();
    //  }
    //  else if (prevGroupId!=-1 && gId!=-1 && prevGroupId!=gId)
    //  {
    //    ol.memberGroupSpacing(TRUE);
    //    ol.memberGroupSeparator();
    //  }
    //}
    
    HtmlHelp *htmlHelp=0;
    bool hasHtmlHelp = Config::instance()->getBool("GENERATE_HTML") && Config::instance()->getBool("GENERATE_HTMLHELP");
    if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();
    
    // search for the last anonymous scope in the member type
    ClassDef *annoClassDef=0;
    //while (i!=-1 && cname.find(ltype.mid(i,l))!=-1)
    //{
    //  i=r.match(ltype,i+l,&l);
    //}
    int il=i-1,ir=i+l;
    if (i!=-1) // found anonymous scope in type
    {
      // extract anonymous scope
      while (il>=0 && (isId(ltype.at(il)) || ltype.at(il)==':' || ltype.at(il)=='@')) il--;
      if (il>0) il++;
      while (ir<(int)ltype.length() && (isId(ltype.at(ir)) || ltype.at(ir)==':' || ltype.at(ir)=='@')) ir++;

      //QCString annName = ltype.mid(i,l);
      QCString annName = ltype.mid(il,ir-il);
      
      // if inside a class or namespace try to prepend the scope name
      if ((cd || nd) && annName.left(cname.length())!=cname) 
      {
        QCString ts=stripAnnonymousNamespaceScope(cname+"::"+annName);
        //printf("Member::writeDeclaration: Trying %s\n",ts.data());
        annoClassDef=getClass(ts);
      }
      // if not found yet, try without scope name
      if (annoClassDef==0)
      {
        QCString ts=stripAnnonymousNamespaceScope(annName);
        //printf("Member::writeDeclaration: Trying %s\n",ts.data());
        annoClassDef=getClass(ts);
      }
    }

    // start a new member declaration
    ol.startMemberItem((annoClassDef || annMemb || annEnumType) ? 1 : 0);
    
    // If there is no detailed description we need to write the anchor here.
    bool detailsVisible = detailsAreVisible();
    if (!detailsVisible && !Config::instance()->getBool("EXTRACT_ALL") && !annMemb)
    {
      QCString doxyName=name().copy();
      if (!cname.isEmpty()) doxyName.prepend(cname+"::");
      ol.startDoxyAnchor(cfname,anchor(),doxyName);

      ol.addIndexItem(name(),cname);
      ol.addIndexItem(cname,name());

      if (hasHtmlHelp)
      {
        htmlHelp->addIndexItem(cname,name(),cfname,anchor());
      }
      ol.pushGeneratorState();
      ol.disable(OutputGenerator::Man);
      ol.docify("\n");
      ol.popGeneratorState();
    }

    //printf("member name=%s indDepth=%d\n",name().data(),indDepth);
    if (annoClassDef || annMemb)
    {
      int j;
      for (j=0;j<indDepth;j++) 
      {
        ol.writeNonBreakableSpace(3);
      }
    }
    
    if (tArgList)
    {
      writeTemplatePrefix(ol,tArgList,FALSE);
    }
    else if (membTAL)
    {
      writeTemplatePrefix(ol,membTAL,FALSE);
    }
    
    if (i!=-1) // member has an anonymous type
    {
      //printf("annoClassDef=%p annMemb=%p scopeName=`%s' anonymous=`%s'\n",
      //    annoClassDef,annMemb,cname.data(),ltype.mid(i,l).data());

      if (annoClassDef) // type is an anonymous compound
      {
        //printf("class found!\n");
        annoClassDef->writeDeclaration(ol,annMemb,inGroup);
        ol.startMemberItem(2);
        int j;
        for (j=0;j<indDepth;j++) 
        {
          ol.writeNonBreakableSpace(3);
        }
        QCString varName=ltype.right(ltype.length()-ir).stripWhiteSpace();
        ol.docify("}");
        if (varName.isEmpty() && (name().isEmpty() || name().at(0)=='@')) 
        {
          ol.docify(";"); 
        }
        else 
        {
          ol.docify(varName);
        }
      }
      else
      {
        if (getAnonymousEnumType()) // type is an anonymous enum
        {
          linkifyText(TextGeneratorOLImpl(ol),cname,name(),ltype.left(i),TRUE); 
          ol+=*getAnonymousEnumType()->enumDecl();
          linkifyText(TextGeneratorOLImpl(ol),cname,name(),ltype.right(ltype.length()-i-l),TRUE); 
        }
        else
        {
          ltype = ltype.left(i) + " { ... } " + ltype.right(ltype.length()-i-l);
          linkifyText(TextGeneratorOLImpl(ol),cname,name(),ltype,TRUE); 
        }
      }
    }
    else
    {
      linkifyText(TextGeneratorOLImpl(ol),cname,name(),ltype,TRUE); 
    }
    bool htmlOn = ol.isEnabled(OutputGenerator::Html);
    if (htmlOn && Config::instance()->getBool("HTML_ALIGN_MEMBERS") && !ltype.isEmpty())
    {
      ol.disable(OutputGenerator::Html);
    }
    if (!ltype.isEmpty()) ol.docify(" ");
    if (htmlOn) 
    {
      ol.enable(OutputGenerator::Html);
    }

    if (annMemb) 
    {
      //bool latexOn = ol.isEnabled(OutputGenerator::Latex);
      //bool manOn   = ol.isEnabled(OutputGenerator::Man);
      //if (latexOn) ol.disable(OutputGenerator::Latex);
      //if (manOn)   ol.disable(OutputGenerator::Man);
      ol.pushGeneratorState();
      ol.disableAllBut(OutputGenerator::Html);
      ol.writeNonBreakableSpace(3);
      ol.popGeneratorState();
      //if (latexOn) ol.enable(OutputGenerator::Latex);
      //if (manOn)   ol.enable(OutputGenerator::Man);
    }
    else
    {
      ol.insertMemberAlign();
    }
    
    // write name
    if (!name().isEmpty() && name().at(0)!='@')
    {
      if (isLinkable())
      {
        if (annMemb)
        {
          //printf("anchor=%s ann_anchor=%s\n",anchor(),annMemb->anchor());
          annMemb->writeLink(ol,
              annMemb->getClassDef(),
              annMemb->getNamespaceDef(),
              annMemb->getFileDef(),
              annMemb->getGroupDef()
                            );
          annMemb->annUsed=annUsed=TRUE;
        }
        else
          //printf("writeLink %s->%d\n",name.data(),hasDocumentation());
          writeLink(ol,cd,nd,fd,gd);
      }
      else // there is a brief member description and brief member 
        // descriptions are enabled or there is no detailed description.
      {
        if (annMemb) annMemb->annUsed=annUsed=TRUE;
        ol.startBold();
        ol.docify(name());
        ol.endBold();
      }
    }

    // if member template specifiers are not part of the name, but they are
    // present, we add them
    //if (tArgList && !(name().find('<')!=-1 && name().find('>')!=-1)
    //    && cd && cd->templateArguments())
    //{
    //  ol.docify(tempArgListToString(tArgList));
    //}

    if (argsString()) 
    {
      if (!isDefine()) ol.writeString(" ");
      //ol.docify(argsString());
      linkifyText(TextGeneratorOLImpl(ol),cname,name(),argsString()); 
    }
    
    if (excpString())
    {
      ol.writeString(" ");
      ol.docify(excpString());
    }

    if (!bitfields.isEmpty()) // add bitfields
    {
      linkifyText(TextGeneratorOLImpl(ol),cname,name(),bitfields.simplifyWhiteSpace());
    }
    else if (!init.isEmpty() && initLines==0 && // one line initializer
             ((maxInitLines>0 && userInitLines==-1) || userInitLines>0) // enabled by default or explicitly
            ) // add initializer
    {
      if (!isDefine()) 
      {
        ol.writeString(" = "); 
        linkifyText(TextGeneratorOLImpl(ol),cname,name(),init.simplifyWhiteSpace());
      }
      else 
      {
        ol.writeNonBreakableSpace(3);
        linkifyText(TextGeneratorOLImpl(ol),cname,name(),init);
      }
    }

    if (!detailsVisible && !Config::instance()->getBool("EXTRACT_ALL") && !annMemb)
    {
      ol.endDoxyAnchor(cfname,anchor());
    }

    ol.endMemberItem((annoClassDef!=0 && indDepth==0) || annEnumType);
    
    //ol.endMemberItem(gId!=-1,gFile,gHeader,annoClassDef || annMemb);
    // write brief description
    if (!briefDescription().isEmpty() && Config::instance()->getBool("BRIEF_MEMBER_DESC") && !annMemb)
    {
      ol.startMemberDescription();
      parseDoc(ol,defFileName,defLine,cname,name(),briefDescription());
      if (/*!documentation().isEmpty()*/ detailsAreVisible()) 
      {
        ol.pushGeneratorState();
        ol.disableAllBut(OutputGenerator::Html);
        ol.endEmphasis();
        ol.docify(" ");
        if (group!=0 && gd==0) // forward link to the group
        {
          ol.startTextLink(group->getOutputFileBase(),anchor());
        }
        else
        {
          ol.startTextLink(0,anchor());
        }
        parseText(ol,theTranslator->trMore());
        ol.endTextLink();
        ol.startEmphasis();
        ol.popGeneratorState();
      }
      //ol.newParagraph();
      ol.endMemberDescription();
    }
  }
  warnIfUndocumented();
}

/*! Writes the "detailed documentation" section of this member to
 *  all active output formats.
 */
void MemberDef::writeDocumentation(MemberList *ml,OutputList &ol,
                                   const char *scName,
                                   Definition *container
                                  )
{
  // hide global static functions unless extractStaticFlag is enabled
  if (getClassDef()==0 && isStatic() && !Config::instance()->getBool("EXTRACT_STATIC")) return;
  // hide member that are documented in their own group
  if (group!=0 && container->definitionType()!=TypeGroup) return;

  // if this member is in a group find the real scope name.
  QCString scopeName = scName;
  if (container->definitionType()==TypeGroup)
  {
    if (getClassDef())          scopeName=getClassDef()->name();
    else if (getNamespaceDef()) scopeName=getNamespaceDef()->name();
    else if (getFileDef())      scopeName=getFileDef()->name();
  }
  
  bool hasDocs = detailsAreVisible();
  //printf("MemberDef::writeDocumentation(): type=`%s' def=`%s'\n",type.data(),definition());
  if (
      Config::instance()->getBool("EXTRACT_ALL") || hasDocs 
      || /* member is part of an anonymous scope that is the type of
          * another member in the list.
          */ 
       (!hasDocs && !briefDescription().isEmpty() && annUsed)
     )
  {
    // get definition. 
    QCString cname  = container->name();
    QCString cfname = container->getOutputFileBase();  

    
    // get member name
    QCString doxyName=name().copy();
    // prepend scope if there is any. TODO: make this optional for C only docs
    if (scopeName) doxyName.prepend((QCString)scopeName+"::");

    QCString ldef = definition();
    if (isEnumerate()) 
    {
      if (name().at(0)=='@')
      {
        ldef = "anonymous enum";
      }
      else
      {
        ldef.prepend("enum ");
      }
    }
    int i=0,l;
    static QRegExp r("@[0-9]+");

    if (isEnumValue()) return;

    ol.pushGeneratorState();

    bool hasHtmlHelp = Config::instance()->getBool("GENERATE_HTML") && Config::instance()->getBool("GENERATE_HTMLHELP");
    HtmlHelp *htmlHelp = 0;
    if (hasHtmlHelp) htmlHelp = HtmlHelp::getInstance();

    if ((isVariable() || isTypedef()) && (i=r.match(ldef,0,&l))!=-1)
    {
      // find enum type and insert it in the definition
      MemberListIterator vmli(*ml);
      MemberDef *vmd;
      bool found=FALSE;
      for ( ; (vmd=vmli.current()) && !found ; ++vmli)
      {
        if (vmd->isEnumerate() && ldef.mid(i,l)==vmd->name())
        {
          ol.startDoxyAnchor(cfname,anchor(),doxyName);
          ol.startMemberDoc(cname,name(),anchor(),name());
          if (hasHtmlHelp)
          {
            htmlHelp->addIndexItem(cname,name(),cfname,anchor());
          }
          linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),ldef.left(i));
          ol+=*vmd->enumDecl();
          linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),ldef.right(ldef.length()-i-l));

          found=TRUE;
        }
      }
      if (!found) // anonymous compound
      {
        //printf("Annonymous compound `%s'\n",cname.data());
        ol.startDoxyAnchor(cfname,anchor(),doxyName);
        ol.startMemberDoc(cname,name(),anchor(),name());
        if (hasHtmlHelp)
        {
          htmlHelp->addIndexItem(cname,name(),cfname,anchor());
        }
        // strip anonymous compound names from definition
        int si=ldef.find(' '),pi,ei=i+l;
        if (si==-1) si=0;
        while ((pi=r.match(ldef,i+l,&l))!=-1) ei=i=pi+l;
        // first si characters of ldef contain compound type name
        ol.startMemberDocName();
        ol.docify(ldef.left(si));
        ol.docify(" { ... } ");
        // last ei characters of ldef contain pointer/reference specifiers
        int ni=ldef.find("::",si);
        if (ni>=ei) ei=ni+2;
        linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),ldef.right(ldef.length()-ei));
      }
    }
    else
    {
      ol.startDoxyAnchor(cfname,anchor(),doxyName);
      ol.startMemberDoc(cname,name(),anchor(),name());
      if (hasHtmlHelp)
      {
        htmlHelp->addIndexItem(cname,name(),cfname,anchor());
      }

      ClassDef *cd=getClassDef();
      ArgumentList *scopeAl=scopeDefTemplateArguments();
      if (scopeAl==0 && cd) scopeAl=cd->templateArguments(); 

      ArgumentList *membAl=memberDefTemplateArguments();
      if (membAl==0) membAl=templateArguments();

      //if (cd && (!isRelated() || templateArguments()!=0) && 
      //    ((al=scopeDefTemplateArguments()) || (al=cd->templateArguments()))
      //   ) 
      if (!Config::instance()->getBool("HIDE_SCOPE_NAMES"))
      {
        if (scopeAl && !related) // class template prefix
        {
          ol.startMemberDocPrefixItem();
          writeTemplatePrefix(ol,scopeAl);
          ol.endMemberDocPrefixItem();
        }
        if (scopeAl && membAl) ol.docify(" ");

        if (membAl) // function template prefix
        {
          ol.startMemberDocPrefixItem();
          writeTemplatePrefix(ol,membAl);
          ol.endMemberDocPrefixItem();
        }
        if (cd)
        {
          QCString cName=cd->name();
          //printf("cName=%s\n",cName.data());
          int il=cName.find('<');
          int ir=cName.findRev('>');
          if (il!=-1 && ir!=-1 && ir>il)
          {
            ldef=addTemplateNames(ldef,
                cName.left(il),          /* class without template spec */
                cName.mid(il,ir-il+1)    /* templ spec */
                                ); 
          }
          else if (scopeAl)
          {
            ldef=addTemplateNames(ldef,cName,tempArgListToString(scopeAl));
          }
        }
      }
      ol.startMemberDocName();
      linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),ldef);
      writeDefArgumentList(ol,cd,scopeName,this);
      if (!init.isEmpty() && initLines==0 && // one line initializer
             ((maxInitLines>0 && userInitLines==-1) || userInitLines>0) // enabled by default or explicitly
         ) // add initializer
      {
        if (!isDefine()) 
        {
          ol.docify(" = "); 
          linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),init.simplifyWhiteSpace());
        }
        else 
        {
          ol.writeNonBreakableSpace(3);
          linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),init);
        }
      }
      if (excpString()) // add exception list
      {
        ol.docify(" ");
        linkifyText(TextGeneratorOLImpl(ol),scopeName,name(),excpString());
      }
    }

    Specifier lvirt=virtualness();
    MemberDef *rmd=reimplements();
    while (rmd && lvirt==Normal)
    {
      lvirt = rmd->virtualness()==Normal ? Normal : Virtual;
      rmd  = rmd->reimplements();
    }

    if (protection()!=Public || lvirt!=Normal ||
        isFriend() || isRelated() || isExplicit() ||
        isMutable() || (isInline() && Config::instance()->getBool("INLINE_INFO")) ||
        isSignal() || isSlot() ||
        isStatic()
       )
    {
      // write the member specifier list
      ol.writeLatexSpacing();
      ol.startTypewriter();
      ol.docify(" [");
      QStrList sl;
      if (isFriend()) sl.append("friend");
      else if (isRelated()) sl.append("related");
      else
      {
        if      (Config::instance()->getBool("INLINE_INFO") && isInline())              
                                          sl.append("inline");
        if      (isExplicit())            sl.append("explicit");
        if      (isMutable())             sl.append("mutable");
        if      (isStatic())              sl.append("static");
        if      (protection()==Protected) sl.append("protected");
        else if (protection()==Private)   sl.append("private");
        if      (lvirt==Virtual)          sl.append("virtual");
        else if (lvirt==Pure)             sl.append("pure virtual");
        if      (isSignal())              sl.append("signal");
        if      (isSlot())                sl.append("slot");
      }
      const char *s=sl.first();
      while (s)
      {
        ol.docify(s);
        s=sl.next();
        if (s) ol.docify(", ");
      }
      ol.docify("]");
      ol.endTypewriter();
    }
    if (!isDefine()) ol.endParameter(TRUE);
    ol.endMemberDoc();
    ol.endDoxyAnchor(cfname,anchor());
    ol.startIndent();
    
    ol.pushGeneratorState();
    ol.disable(OutputGenerator::RTF);
    ol.newParagraph();
    ol.popGeneratorState();

    /* write multi-line initializer (if any) */
    if (initLines>0 && ((initLines<maxInitLines && userInitLines==-1) // implicitly enabled
                        || initLines<userInitLines // explicitly enabled
                       )
       )
    {
      ol.startBold();
      if (mtype==Define)
        parseText(ol,theTranslator->trDefineValue());
      else
        parseText(ol,theTranslator->trInitialValue());
      ol.endBold();
      initParseCodeContext();
      ol.startCodeFragment();
      parseCode(ol,scopeName,init,FALSE,0);
      ol.endCodeFragment();
    }
    
    /* write brief description */
    if (!briefDescription().isEmpty() && 
        (Config::instance()->getBool("REPEAT_BRIEF")  
         /* || (!Config::instance()->getBool("BRIEF_MEMBER_DESC") && documentation().isEmpty())*/
        ) /* || !annMemb */
       )  
    { 
      parseDoc(ol,defFileName,defLine,scopeName,name(),briefDescription());
      ol.newParagraph();
    }

    /* write detailed description */
    if (!documentation().isEmpty())
    { 
      parseDoc(ol,defFileName,defLine,scopeName,name(),documentation()+"\n");
      ol.pushGeneratorState();
      ol.disableAllBut(OutputGenerator::RTF);
      ol.newParagraph();
      ol.popGeneratorState();
    }

    //printf("***** argList=%p name=%s docs=%s hasDocs=%d\n",
    //     argList, 
    //     argList?argList->hasDocumentation():-1);
    if (argList && argList->hasDocumentation())
    {
      //printf("***** argumentList is documented\n");
      ol.startDescList();
      ol.startBold();
      parseText(ol,theTranslator->trParameters()+": ");
      ol.endBold();
      ol.endDescTitle();
      ol.writeDescItem();
      ol.startDescTable();
      ArgumentListIterator ali(*argList);
      Argument *a;
      for (ali.toFirst();(a=ali.current());++ali)
      {
        if (a->hasDocumentation())
        {
          ol.startDescTableTitle();
          ol.startEmphasis();
          ol.docify(a->name);
          ol.endEmphasis();
          ol.endDescTableTitle();
          ol.startDescTableData();
          parseDoc(ol,defFileName,defLine,scopeName,name(),a->docs);
          ol.endDescTableData();
        }
      }
      ol.endDescTable();
      ol.endDescList();
    }
    
    if (isEnumerate())
    {
      bool first=TRUE;
      MemberList *fmdl=enumFieldList();
      if (fmdl)
      {
        MemberDef *fmd=fmdl->first();
        while (fmd)
        {
          if (fmd->isLinkable())
          {
            if (first)
            {
              //ol.newParagraph();
              ol.startDescList();
              ol.startBold();
              parseText(ol,theTranslator->trEnumerationValues());
              ol.docify(":");
              ol.endBold();
              ol.endDescTitle();
              ol.writeDescItem();
              //ol.startItemList();
              ol.startDescTable();
            }

            ol.addIndexItem(fmd->name(),cname);
            ol.addIndexItem(cname,fmd->name());

            if (Config::instance()->getBool("GENERATE_HTML") && Config::instance()->getBool("GENERATE_HTMLHELP"))
            {
              HtmlHelp::getInstance()->addIndexItem(cname,fmd->name(),cfname,fmd->anchor());
            }
            //ol.writeListItem();
            ol.startDescTableTitle();
            ol.startDoxyAnchor(cfname,fmd->anchor(),fmd->name());
            first=FALSE;
            ol.startEmphasis();
            ol.docify(fmd->name());
            ol.endEmphasis();
            ol.disableAllBut(OutputGenerator::Man);
            ol.writeString(" ");
            ol.enableAll();
            ol.endDoxyAnchor(cfname,fmd->anchor());
            ol.endDescTableTitle();
            //ol.newParagraph();
            ol.startDescTableData();

            if (!fmd->briefDescription().isEmpty())
            { 
              parseDoc(ol,defFileName,defLine,scopeName,fmd->name(),fmd->briefDescription());
              //ol.newParagraph();
            }
            if (!fmd->briefDescription().isEmpty() && 
                !fmd->documentation().isEmpty())
            {
              ol.newParagraph();
            }
            if (!fmd->documentation().isEmpty())
            { 
              parseDoc(ol,defFileName,defLine,scopeName,fmd->name(),fmd->documentation()+"\n");
            }
            ol.endDescTableData();
          }
          fmd=fmdl->next();
        }
      }
      if (!first) 
      { 
        //ol.endItemList(); 
        ol.endDescTable();
        ol.endDescList();
        ol.writeChar('\n'); 
      }
    }

    MemberDef *bmd=reimplements();
    ClassDef  *bcd=0; 
    if (bmd && (bcd=bmd->getClassDef()))
    {
#if 0
      if (lvirt!=Normal) // search for virtual member of the deepest base class
      {
        MemberDef *lastBmd=bmd;
        while (lastBmd) 
        {
          ClassDef *lastBcd = lastBmd->getClassDef();
          if (lastBmd->virtualness()!=Normal && 
              lastBmd->isLinkable() &&
              lastBcd->isLinkable()
             ) { bmd=lastBmd; bcd=lastBcd; }
          lastBmd=lastBmd->reimplements();
        }
      }
#endif
      // write class that contains a member that is reimplemented by this one
      if (bcd->isLinkable())
      {
        ol.newParagraph();

        QCString reimplFromLine = theTranslator->trReimplementedFromList(1);
        int markerPos = reimplFromLine.find("@0");
        if (markerPos!=-1) // should always pass this.
        {
          parseText(ol,reimplFromLine.left(markerPos)); //text left from marker
          if (bmd->isLinkable()) // replace marker with link
          {
            ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
                bmd->anchor(),bcd->name());
            if ( bcd->isLinkableInProject()/* && !Config::instance()->getBool("PDF_HYPERLINKS")*/ ) 
            {
              writePageRef(ol,bcd->getOutputFileBase(),bmd->anchor());
            }
          }
          else
          {
            ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
                0,bcd->name());
            if (bcd->isLinkableInProject()/* && !Config::instance()->getBool("PDF_HYPERLINKS")*/ )
            {
              writePageRef(ol,bcd->getOutputFileBase(),0);
            }
          }
          parseText(ol,reimplFromLine.right(
                reimplFromLine.length()-markerPos-2)); // text right from marker

          ol.disableAllBut(OutputGenerator::RTF);
          ol.newParagraph();
          ol.enableAll();
        }
        else
        {
          err("Error: translation error: no marker in trReimplementsFromList()\n");
        }
      }

      //ol.writeString(".");
    }
    MemberList *bml=reimplementedBy();
    if (bml)
    {
      MemberListIterator mli(*bml);
      MemberDef *bmd=0;
      uint count=0;
      ClassDef *bcd=0;
      for (mli.toFirst();(bmd=mli.current()) && (bcd=bmd->getClassDef());++mli)
      {
        // count the members that directly inherit from md and for
        // which the member and class are visible in the docs.
        if ( bmd->isLinkable() && bcd->isLinkable() ) count++;
      }
      if (count>0)
      {
        mli.toFirst();
        // write the list of classes that overwrite this member
        ol.newParagraph();

        QCString reimplInLine = 
          theTranslator->trReimplementedInList(count);
        static QRegExp marker("@[0-9]+");
        int index=0,newIndex,matchLen;
        // now replace all markers in reimplInLine with links to the classes
        while ((newIndex=marker.match(reimplInLine,index,&matchLen))!=-1)
        {
          parseText(ol,reimplInLine.mid(index,newIndex-index));
          bool ok;
          uint entryIndex = reimplInLine.mid(newIndex+1,matchLen-1).toUInt(&ok);
          //bmd=bml->at(entryIndex);

          count=0;
          // find the entryIndex-th documented entry in the inheritance list.
          for (mli.toLast();(bmd=mli.current()) && (bcd=bmd->getClassDef());--mli)
          {
            if ( bmd->isLinkable() && bcd->isLinkable()) 
            {
              if (count==entryIndex) break;
              count++;
            }
          }

          if (ok && bcd && bmd) // write link for marker
          {
            ol.writeObjectLink(bcd->getReference(),bcd->getOutputFileBase(),
                bmd->anchor(),bcd->name());
            if (bcd->isLinkableInProject()/* && !Config::instance()->getBool("PDF_HYPERLINKS")*/ ) 
            {
              writePageRef(ol,bcd->getOutputFileBase(),bmd->anchor());
            }
          }
          ++mli;
          index=newIndex+matchLen;
        } 
        parseText(ol,reimplInLine.right(reimplInLine.length()-index));
        ol.disableAllBut(OutputGenerator::RTF);
        ol.newParagraph();
        ol.enableAll();
      }
    }
    // write the list of examples that use this member
    if (hasExamples())
    {
      ol.startDescList();
      ol.startBold();
      parseText(ol,theTranslator->trExamples()+": ");
      //ol.writeBoldString("Examples: ");
      ol.endBold();
      ol.endDescTitle();
      ol.writeDescItem();
      writeExample(ol,getExampleList());
      //ol.endDescItem();
      ol.endDescList();
    }
    // write reference to the source
    writeSourceDef(ol,cname);
    writeSourceRefs(ol,cname);
    writeInlineCode(ol,cname);

    ol.endIndent();
    // enable LaTeX again
    //if (Config::instance()->getBool("EXTRACT_ALL") && !hasDocs) ol.enable(OutputGenerator::Latex); 
    ol.popGeneratorState();

  }
}

void MemberDef::warnIfUndocumented()
{
  if (memberGroup) return;
  ClassDef     *cd = getClassDef();
  NamespaceDef *nd = getNamespaceDef();
  FileDef      *fd = getFileDef();
  GroupDef     *gd = getGroupDef();
  Definition *d=0;
  const char *t=0;
  if (cd) 
    t="class", d=cd; 
  else if (nd) 
    t="namespace", d=nd; 
  else if (gd)
    t="group", d=gd;
  else
    t="file", d=fd;

  if (d && d->isLinkable() && !isLinkable() && name().find('@')==-1)
   warn_undoc(defFileName,defLine,"Warning: Member %s of %s %s is not documented.",
        name().data(),t,d->name().data());
}


bool MemberDef::isLinkableInProject()
{
  return !name().isEmpty() && name().at(0)!='@' &&
         ((hasDocumentation() && !isReference())  
         ) && 
         (prot!=Private || Config::instance()->getBool("EXTRACT_PRIVATE") || isFriend()) && // not a private class member
         (classDef!=0 || Config::instance()->getBool("EXTRACT_STATIC") || !isStatic()); // not a static file/namespace member
}

bool MemberDef::isLinkable()
{
  return isLinkableInProject() || isReference();
}

bool MemberDef::detailsAreVisible() const          
{ 
  return !documentation().isEmpty() || // has detailed docs
         //((Config::instance()->getBool("SOURCE_BROWSER") || Config::instance()->getBool("INLINE_SOURCES")) && startBodyLine!=-1 && bodyDef) ||  // has reference to sources 
         (mtype==Enumeration && docEnumValues) ||  // has enum values
         (mtype==EnumValue && !briefDescription().isEmpty()) || // is doc enum value
         (!briefDescription().isEmpty() && 
           (!Config::instance()->getBool("BRIEF_MEMBER_DESC") || Config::instance()->getBool("ALWAYS_DETAILED_SEC")) && 
           Config::instance()->getBool("REPEAT_BRIEF") // has brief description inside detailed area
         ) ||
         (initLines>0 && initLines<maxInitLines) ||
         (argList!=0 && argList->hasDocumentation())
         ;
}

void MemberDef::setEnumDecl(OutputList &ed) 
{ 
  enumDeclList=new OutputList(&ed); 
  *enumDeclList+=ed;
}

bool MemberDef::hasDocumentation()
{ 
  return Definition::hasDocumentation() || (argList!=0 && argList->hasDocumentation()); 
}

void MemberDef::setMemberGroup(MemberGroup *grp)
{
  memberGroup = grp;
}

bool MemberDef::visibleMemberGroup(bool hideNoHeader) 
{ 
  return memberGroup!=0 && 
          (!hideNoHeader || memberGroup->header()!="[NOHEADER]"); 
}

QCString MemberDef::getScopeString() const
{
  QCString result;
  if (getClassDef()) result=getClassDef()->name();
  else if (getNamespaceDef()) result=getNamespaceDef()->name();
  return result;
}


//Definition *MemberDef::getCompoundDef() const
//{
//    NamespaceDef *nd=getNamespaceDef();
//    ClassDef     *cd=getClassDef();
//    FileDef      *fd=getFileDef();
//    GroupDef     *gd=getGroupDef();
//    Definition   *d = 0;
//    if (cd) d=cd; else if (nd) d=nd; else if (gd) d=gd; else d=fd;
//    ASSERT(d!=0);
//    return d;
//}

QCString MemberDef::anchor() const
{
  if (enumScope) return enumScope->anchor()+anc;
  return anc;
}