1 /******************************************************************************
3 * $Id: def.cpp,v 1.2 2001/01/01 10:15:18 root Exp $
6 * Copyright (C) 1997-2012 by Dimitri van Heesch.
8 * Permission to use, copy, modify, and distribute this software and its
9 * documentation under the terms of the GNU General Public License is hereby
10 * granted. No representations are made about the suitability of this software
11 * for any purpose. It is provided "as is" without express or implied warranty.
12 * See the GNU General Public License for more details.
14 * Documents produced by Doxygen are derivative works derived from the
15 * input used in their production; they are not affected by this license.
26 #include "classlist.h"
29 #include "outputgen.h"
31 #include "arguments.h"
35 #include <qtextstream.h>
39 inline void writeDEFString(FTextStream &t,const char *s)
54 void generateDEFForMember(MemberDef *md,
65 // - const/volatile specifiers
67 // + source definition
68 // - source references
69 // - source referenced by
72 if (md->memberType()==MemberDef::EnumValue) return;
75 if (md->getClassDef())
76 scopeName=md->getClassDef()->name();
77 else if (md->getNamespaceDef())
78 scopeName=md->getNamespaceDef()->name();
80 t << " " << Prefix << "-member = {" << endl;
82 memPrefix.append( Prefix );
83 memPrefix.append( "-mem-" );
87 switch (md->memberType())
89 case MemberDef::Define: memType="define"; break;
90 case MemberDef::EnumValue: ASSERT(0); break;
91 case MemberDef::Property: memType="property"; break;
92 case MemberDef::Event: memType="event"; break;
93 case MemberDef::Variable: memType="variable"; break;
94 case MemberDef::Typedef: memType="typedef"; break;
95 case MemberDef::Enumeration: memType="enum"; break;
96 case MemberDef::Function: memType="function"; isFunc=TRUE; break;
97 case MemberDef::Signal: memType="signal"; isFunc=TRUE; break;
98 case MemberDef::Friend: memType="friend"; isFunc=TRUE; break;
99 case MemberDef::DCOP: memType="dcop"; isFunc=TRUE; break;
100 case MemberDef::Slot: memType="slot"; isFunc=TRUE; break;
103 t << memPrefix << "kind = '" << memType << "';" << endl;
104 t << memPrefix << "id = '"
105 << md->getOutputFileBase() << "_1" << md->anchor()
108 t << memPrefix << "virt = ";
109 switch (md->virtualness())
111 case Normal: t << "normal;" << endl; break;
112 case Virtual: t << "virtual;" << endl; break;
113 case Pure: t << "pure-virtual;" << endl; break;
117 t << memPrefix << "prot = ";
118 switch(md->protection())
120 case Public: t << "public;" << endl; break;
121 case Protected: t << "protected;" << endl; break;
122 case Private: t << "private;" << endl; break;
123 case Package: t << "package;" << endl; break;
126 if (md->memberType()!=MemberDef::Define &&
127 md->memberType()!=MemberDef::Enumeration
130 QCString typeStr = replaceAnonymousScopes(md->typeString());
131 t << memPrefix << "type = <<_EnD_oF_dEf_TeXt_" << endl << typeStr << endl
132 << "_EnD_oF_dEf_TeXt_;" << endl;
135 t << memPrefix << "name = '" << md->name() << "';" << endl;
137 if (isFunc) //function
139 ArgumentList *declAl = new ArgumentList;
140 LockingPtr<ArgumentList> defAl = md->argumentList();
141 stringToArgumentList(md->argsString(),declAl);
142 QCString fcnPrefix = " " + memPrefix + "param-";
144 if (declAl->count()>0)
146 ArgumentListIterator declAli(*declAl);
147 ArgumentListIterator defAli(*defAl);
149 for (declAli.toFirst();(a=declAli.current());++declAli)
151 Argument *defArg = defAli.current();
152 t << memPrefix << "param = {" << endl;
153 if (!a->attrib.isEmpty())
155 t << fcnPrefix << "attributes = ";
156 writeDEFString(t,a->attrib);
159 if (!a->type.isEmpty())
161 t << fcnPrefix << "type = <<_EnD_oF_dEf_TeXt_" << endl
162 << a->type << endl << "_EnD_oF_dEf_TeXt_;" << endl;
164 if (!a->name.isEmpty())
166 t << fcnPrefix << "declname = ";
167 writeDEFString(t,a->name);
170 if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
172 t << fcnPrefix << "defname = ";
173 writeDEFString(t,defArg->name);
176 if (!a->array.isEmpty())
178 t << fcnPrefix << "array = ";
179 writeDEFString(t,a->array);
182 if (!a->defval.isEmpty())
184 t << fcnPrefix << "defval = <<_EnD_oF_dEf_TeXt_" << endl
185 << a->defval << endl << "_EnD_oF_dEf_TeXt_;" << endl;
187 if (defArg) ++defAli;
188 t << " }; /*" << fcnPrefix << "-param */" << endl;
193 else if ( md->memberType()==MemberDef::Define
194 && md->argsString()!=0)
196 ArgumentListIterator ali(*md->argumentList());
198 QCString defPrefix = " " + memPrefix + "def-";
200 for (ali.toFirst();(a=ali.current());++ali)
202 t << memPrefix << "param = {" << endl;
203 t << defPrefix << "name = '" << a->type << "';" << endl;
204 t << " }; /*" << defPrefix << "-param */" << endl;
208 if (!md->initializer().isEmpty())
210 t << memPrefix << "initializer = <<_EnD_oF_dEf_TeXt_" << endl
211 << md->initializer() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
213 // TODO: exceptions, const volatile
214 if (md->memberType()==MemberDef::Enumeration) // enum
216 LockingPtr<MemberList> enumList = md->enumFieldList();
219 MemberListIterator emli(*enumList);
221 for (emli.toFirst();(emd=emli.current());++emli)
223 t << memPrefix << "enum = { enum-name = " << emd->name() << ';';
224 if (!emd->initializer().isEmpty())
226 t << " enum-value = ";
227 writeDEFString(t,emd->initializer());
235 t << memPrefix << "desc-file = '" << md->getDefFileName() << "';" << endl;
236 t << memPrefix << "desc-line = '" << md->getDefLine() << "';" << endl;
237 t << memPrefix << "briefdesc = <<_EnD_oF_dEf_TeXt_" << endl
238 << md->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
239 t << memPrefix << "documentation = <<_EnD_oF_dEf_TeXt_" << endl
240 << md->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
242 //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers());
244 LockingPtr<MemberSDict> mdict = md->getReferencesMembers();
247 MemberSDict::Iterator mdi(*mdict);
249 QCString refPrefix = " " + memPrefix + "ref-";
251 for (mdi.toFirst();(rmd=mdi.current());++mdi)
253 if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
255 t << memPrefix << "referenceto = {" << endl;
256 t << refPrefix << "id = '"
257 << rmd->getBodyDef()->getOutputFileBase()
258 << "_1" // encoded `:' character (see util.cpp:convertNameToFile)
259 << rmd->anchor() << "';" << endl;
261 t << refPrefix << "line = '"
262 << rmd->getStartBodyLine() << "';" << endl;
264 QCString scope = rmd->getScopeString();
265 QCString name = rmd->name();
266 if (!scope.isEmpty() && scope!=def->name())
268 name.prepend(scope+"::");
271 t << refPrefix << "name = ";
272 writeDEFString(t,name);
273 t << ';' << endl << " };" << endl;
275 } /* for (mdi.toFirst...) */
277 mdict = md->getReferencedByMembers();
280 MemberSDict::Iterator mdi(*mdict);
282 QCString refPrefix = " " + memPrefix + "ref-";
284 for (mdi.toFirst();(rmd=mdi.current());++mdi)
286 if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
288 t << memPrefix << "referenceby = {" << endl;
289 t << refPrefix << "id = '"
290 << rmd->getBodyDef()->getOutputFileBase()
291 << "_1" // encoded `:' character (see util.cpp:convertNameToFile)
292 << rmd->anchor() << "';" << endl;
294 t << refPrefix << "line = '"
295 << rmd->getStartBodyLine() << "';" << endl;
297 QCString scope = rmd->getScopeString();
298 QCString name = rmd->name();
299 if (!scope.isEmpty() && scope!=def->name())
301 name.prepend(scope+"::");
304 t << refPrefix << "name = ";
305 writeDEFString(t,name);
306 t << ';' << endl << " };" << endl;
308 } /* for (mdi.toFirst...) */
311 t << " }; /* " << Prefix << "-member */" << endl;
315 void generateDEFClassSection(ClassDef *cd,
320 if (cd && ml && ml->count()>0)
322 t << " cp-section = {" << endl;
323 t << " sec-kind = '" << kind << "';" << endl;
325 MemberListIterator mli(*ml);
327 for (mli.toFirst();(md=mli.current());++mli)
329 generateDEFForMember(md,t,cd,"sec");
331 t << " }; /* cp-section */" << endl;
335 void generateDEFForClass(ClassDef *cd,FTextStream &t)
337 // + brief description
338 // + detailed description
339 // - template arguments
341 // + inheritance diagram
342 // + list of direct super classes
343 // + list of direct sub classes
344 // + collaboration diagram
345 // - list of all members
346 // + user defined member sections
347 // + standard member sections
348 // + detailed member documentation
351 if (cd->isReference()) return; // skip external references.
352 if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
353 if (cd->templateMaster()!=0) return; // skip generated template instances.
355 t << cd->compoundTypeString() << " = {" << endl;
356 t << " cp-id = '" << cd->getOutputFileBase() << "';" << endl;
357 t << " cp-name = '" << cd->name() << "';" << endl;
359 if (cd->baseClasses())
361 BaseClassListIterator bcli(*cd->baseClasses());
363 for (bcli.toFirst();(bcd=bcli.current());++bcli)
365 t << " cp-ref = {" << endl << " ref-type = base;" << endl;
367 << bcd->classDef->getOutputFileBase() << "';" << endl;
371 case Public: t << "public;" << endl; break;
372 case Package: // package scope is not possible
373 case Protected: t << "protected;" << endl; break;
374 case Private: t << "private;" << endl; break;
379 case Normal: t << "non-virtual;"; break;
380 case Virtual: t << "virtual;"; break;
381 case Pure: t << "pure-virtual;"; break;
383 t << endl << " };" << endl;
387 if (cd->subClasses())
389 BaseClassListIterator bcli(*cd->subClasses());
391 for (bcli.toFirst();(bcd=bcli.current());++bcli)
393 t << " cp-ref = {" << endl << " ref-type = derived;" << endl;
395 << bcd->classDef->getOutputFileBase() << "';" << endl;
399 case Public: t << "public;" << endl; break;
400 case Package: // packet scope is not possible!
401 case Protected: t << "protected;" << endl; break;
402 case Private: t << "private;" << endl; break;
407 case Normal: t << "non-virtual;"; break;
408 case Virtual: t << "virtual;"; break;
409 case Pure: t << "pure-virtual;"; break;
411 t << endl << " };" << endl;
416 QListIterator<MemberList> mli(cd->getMemberLists());
418 for (mli.toFirst();(ml=mli.current());++mli)
420 if ((ml->listType()&MemberList::detailedLists)==0)
422 numMembers+=ml->count();
427 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::pubTypes),"public-type");
428 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::pubMethods),"public-func");
429 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::pubAttribs),"public-attrib");
430 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::pubSlots),"public-slot");
431 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::signals),"signal");
432 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::dcopMethods),"dcop-func");
433 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::properties),"property");
434 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::pubStaticMethods),"public-static-func");
435 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::pubStaticAttribs),"public-static-attrib");
436 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::proTypes),"protected-type");
437 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::proMethods),"protected-func");
438 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::proAttribs),"protected-attrib");
439 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::proSlots),"protected-slot");
440 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::proStaticMethods),"protected-static-func");
441 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::proStaticAttribs),"protected-static-attrib");
442 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::priTypes),"private-type");
443 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::priMethods),"private-func");
444 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::priAttribs),"private-attrib");
445 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::priSlots),"private-slot");
446 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::priStaticMethods),"private-static-func");
447 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::priStaticAttribs),"private-static-attrib");
448 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::friends),"signal");
449 generateDEFClassSection(cd,t,cd->getMemberList(MemberList::related),"related");
452 t << " cp-filename = '" << cd->getDefFileName() << "';" << endl;
453 t << " cp-fileline = '" << cd->getDefLine() << "';" << endl;
454 t << " cp-briefdesc = <<_EnD_oF_dEf_TeXt_" << endl
455 << cd->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
457 t << " cp-documentation = <<_EnD_oF_dEf_TeXt_" << endl
458 << cd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
460 DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
461 if (!inheritanceGraph.isTrivial())
463 t << " cp-inheritancegraph = <<_EnD_oF_dEf_TeXt_" << endl;
464 inheritanceGraph.writeDEF(t);
465 t << endl << "_EnD_oF_dEf_TeXt_;" << endl;
467 DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
468 if (!collaborationGraph.isTrivial())
470 t << " cp-collaborationgraph = <<_EnD_oF_dEf_TeXt_" << endl;
471 collaborationGraph.writeDEF(t);
472 t << endl << "_EnD_oF_dEf_TeXt_;" << endl;
474 t << "}; /* " << cd->compoundTypeString() << " */" << endl;
477 void generateDEFSection(Definition *d,
482 if (ml && ml->count()>0)
484 t << " " << kind << " = {" << endl;
485 MemberListIterator mli(*ml);
487 for (mli.toFirst();(md=mli.current());++mli)
489 generateDEFForMember(md,t,d,kind);
495 void generateDEFForNamespace(NamespaceDef *nd,FTextStream &t)
497 if (nd->isReference()) return; // skip external references
498 t << " namespace = {" << endl;
499 t << " ns-id = '" << nd->getOutputFileBase() << "';" << endl;
501 writeDEFString(t,nd->name());
504 generateDEFSection(nd,t,nd->getMemberList(MemberList::decDefineMembers),"define");
505 generateDEFSection(nd,t,nd->getMemberList(MemberList::decProtoMembers),"prototype");
506 generateDEFSection(nd,t,nd->getMemberList(MemberList::decTypedefMembers),"typedef");
507 generateDEFSection(nd,t,nd->getMemberList(MemberList::decEnumMembers),"enum");
508 generateDEFSection(nd,t,nd->getMemberList(MemberList::decFuncMembers),"func");
509 generateDEFSection(nd,t,nd->getMemberList(MemberList::decVarMembers),"var");
511 t << " ns-filename = '" << nd->getDefFileName() << "';" << endl;
512 t << " ns-fileline = '" << nd->getDefLine() << "';" << endl;
513 t << " ns-briefdesc = <<_EnD_oF_dEf_TeXt_" << endl
514 << nd->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
516 t << " ns-documentation = <<_EnD_oF_dEf_TeXt_" << endl
517 << nd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
521 void generateDEFForFile(FileDef *fd,FTextStream &t)
523 if (fd->isReference()) return; // skip external references
525 t << "file = {" << endl;
526 t << " file-id = '" << fd->getOutputFileBase() << "';" << endl;
527 t << " file-name = ";
528 writeDEFString(t,fd->name());
531 generateDEFSection(fd,t,fd->getMemberList(MemberList::decDefineMembers),"define");
532 generateDEFSection(fd,t,fd->getMemberList(MemberList::decProtoMembers),"prototype");
533 generateDEFSection(fd,t,fd->getMemberList(MemberList::decTypedefMembers),"typedef");
534 generateDEFSection(fd,t,fd->getMemberList(MemberList::decEnumMembers),"enum");
535 generateDEFSection(fd,t,fd->getMemberList(MemberList::decFuncMembers),"func");
536 generateDEFSection(fd,t,fd->getMemberList(MemberList::decVarMembers),"var");
538 t << " file-full-name = '" << fd->getDefFileName() << "';" << endl;
539 t << " file-first-line = '" << fd->getDefLine() << "';" << endl;
541 t << " file-briefdesc = <<_EnD_oF_dEf_TeXt_" << endl
542 << fd->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
544 t << " file-documentation = <<_EnD_oF_dEf_TeXt_" << endl
545 << fd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
547 t << "}; /* file */" << endl;
553 QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
554 if (outputDirectory.isEmpty())
556 outputDirectory=QDir::currentDirPath().utf8();
560 QDir dir(outputDirectory);
563 dir.setPath(QDir::currentDirPath());
564 if (!dir.mkdir(outputDirectory))
566 err("error: tag OUTPUT_DIRECTORY: Output directory `%s' does not "
567 "exist and cannot be created\n",outputDirectory.data());
570 else if (!Config_getBool("QUIET"))
572 err("notice: Output directory `%s' does not exist. "
573 "I have created it for you.\n", outputDirectory.data());
575 dir.cd(outputDirectory);
577 outputDirectory=dir.absPath().utf8();
580 QDir dir(outputDirectory);
583 dir.setPath(QDir::currentDirPath());
584 if (!dir.mkdir(outputDirectory))
586 err("Cannot create directory %s\n",outputDirectory.data());
590 QDir defDir(outputDirectory+"/def");
591 if (!defDir.exists() && !defDir.mkdir(outputDirectory+"/def"))
593 err("Could not create def directory in %s\n",outputDirectory.data());
597 QCString fileName=outputDirectory+"/def/doxygen.def";
599 if (!f.open(IO_WriteOnly))
601 err("Cannot open file %s for writing!\n",fileName.data());
605 t << "AutoGen Definitions dummy;" << endl;
607 if (Doxygen::classSDict->count()+Doxygen::inputNameList->count()>0)
609 ClassSDict::Iterator cli(*Doxygen::classSDict);
611 for (cli.toFirst();(cd=cli.current());++cli)
613 generateDEFForClass(cd,t);
615 FileNameListIterator fnli(*Doxygen::inputNameList);
617 for (;(fn=fnli.current());++fnli)
619 FileNameIterator fni(*fn);
621 for (;(fd=fni.current());++fni)
623 generateDEFForFile(fd,t);
629 t << "dummy_value = true;" << endl;