Imported Upstream version 1.8.15
[platform/upstream/doxygen.git] / src / defgen.cpp
1 /******************************************************************************
2  *
3  * 
4  *
5  *
6  * Copyright (C) 1997-2015 by Dimitri van Heesch.
7  *
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.
13  *
14  * Documents produced by Doxygen are derivative works derived from the
15  * input used in their production; they are not affected by this license.
16  *
17  */
18
19 #include <stdlib.h>
20
21 #include "defgen.h"
22 #include "doxygen.h"
23 #include "message.h"
24 #include "config.h"
25 #include "classlist.h"
26 #include "util.h"
27 #include "defargs.h"
28 #include "outputgen.h"
29 #include "dot.h"
30 #include "arguments.h"
31 #include "memberlist.h"
32 #include "namespacedef.h"
33 #include "filedef.h"
34 #include "filename.h"
35
36 #include <qdir.h>
37 #include <qfile.h>
38 #include <qtextstream.h>
39
40 #define DEF_DB(x)
41
42 inline void writeDEFString(FTextStream &t,const char *s)
43 {
44   const char* p=s;
45   char c;
46
47   t << '\'';
48   while ((c = *(p++)))
49   {
50     if (c == '\'')
51       t << '\\';
52     t << c;
53   }
54   t << '\'';
55 }
56
57 void generateDEFForMember(MemberDef *md,
58     FTextStream &t,
59     Definition *def,
60     const char* Prefix)
61 {
62   QCString memPrefix;
63
64   // + declaration
65   // - reimplements
66   // - reimplementedBy
67   // - exceptions
68   // - const/volatile specifiers
69   // - examples
70   // + source definition
71   // - source references
72   // - source referenced by
73   // - include code 
74
75   if (md->memberType()==MemberType_EnumValue) return;
76
77   QCString scopeName;
78   if (md->getClassDef()) 
79     scopeName=md->getClassDef()->name();
80   else if (md->getNamespaceDef()) 
81     scopeName=md->getNamespaceDef()->name();
82
83   t << "    " << Prefix << "-member = {" << endl;
84   memPrefix = "      ";
85   memPrefix.append( Prefix );
86   memPrefix.append( "-mem-" );
87
88   QCString memType;
89   bool isFunc=FALSE;
90   switch (md->memberType())
91   {
92     case MemberType_Define:      memType="define";     break;
93     case MemberType_EnumValue:   ASSERT(0);            break;
94     case MemberType_Property:    memType="property";   break;
95     case MemberType_Event:       memType="event";      break;
96     case MemberType_Variable:    memType="variable";   break;
97     case MemberType_Typedef:     memType="typedef";    break;
98     case MemberType_Enumeration: memType="enum";       break;
99     case MemberType_Interface:   memType="interface";  break;
100     case MemberType_Service:     memType="service";    break;
101     case MemberType_Sequence:    memType="sequence";   break;
102     case MemberType_Dictionary:  memType="dictionary"; break;
103     case MemberType_Function:    memType="function";   isFunc=TRUE; break;
104     case MemberType_Signal:      memType="signal";     isFunc=TRUE; break;
105     case MemberType_Friend:      memType="friend";     isFunc=TRUE; break;
106     case MemberType_DCOP:        memType="dcop";       isFunc=TRUE; break;
107     case MemberType_Slot:        memType="slot";       isFunc=TRUE; break;
108   }
109
110   t << memPrefix << "kind = '" << memType << "';" << endl;
111   t << memPrefix << "id   = '"
112     << md->getOutputFileBase() << "_1" << md->anchor()
113     << "';" << endl;
114
115   t << memPrefix << "virt = ";
116   switch (md->virtualness())
117   {
118     case Normal:  t << "normal;"       << endl; break;
119     case Virtual: t << "virtual;"      << endl; break;
120     case Pure:    t << "pure-virtual;" << endl; break;
121     default: ASSERT(0);
122   }
123
124   t << memPrefix << "prot = ";
125   switch(md->protection())
126   {
127     case Public:    t << "public;"    << endl; break;
128     case Protected: t << "protected;" << endl; break;
129     case Private:   t << "private;"   << endl; break;
130     case Package:   t << "package;"   << endl; break;
131   }
132
133   if (md->memberType()!=MemberType_Define &&
134       md->memberType()!=MemberType_Enumeration
135      )
136   {
137     QCString typeStr = replaceAnonymousScopes(md->typeString());
138     t << memPrefix << "type = <<_EnD_oF_dEf_TeXt_" << endl << typeStr << endl
139       << "_EnD_oF_dEf_TeXt_;" << endl;
140   }
141
142   t << memPrefix << "name = '" << md->name() << "';" << endl;
143
144   if (isFunc) //function
145   {
146     ArgumentList *declAl = new ArgumentList;
147     ArgumentList *defAl = md->argumentList();
148     stringToArgumentList(md->argsString(),declAl);
149     QCString fcnPrefix = "  " + memPrefix + "param-";
150
151     if (defAl && declAl->count()>0)
152     {
153       ArgumentListIterator declAli(*declAl);
154       ArgumentListIterator defAli(*defAl);
155       Argument *a;
156       for (declAli.toFirst();(a=declAli.current());++declAli)
157       {
158         Argument *defArg = defAli.current();
159         t << memPrefix << "param = {" << endl;
160         if (!a->attrib.isEmpty())
161         {
162           t << fcnPrefix << "attributes = ";
163           writeDEFString(t,a->attrib);
164           t << ';' << endl;
165         }
166         if (!a->type.isEmpty())
167         {
168           t << fcnPrefix << "type = <<_EnD_oF_dEf_TeXt_" << endl
169             << a->type << endl << "_EnD_oF_dEf_TeXt_;" << endl;
170         }
171         if (!a->name.isEmpty())
172         {
173           t << fcnPrefix << "declname = ";
174           writeDEFString(t,a->name);
175           t << ';' << endl;
176         }
177         if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
178         {
179           t << fcnPrefix << "defname = ";
180           writeDEFString(t,defArg->name);
181           t << ';' << endl;
182         }
183         if (!a->array.isEmpty())
184         {
185           t << fcnPrefix << "array = ";
186           writeDEFString(t,a->array); 
187           t << ';' << endl;
188         }
189         if (!a->defval.isEmpty())
190         {
191           t << fcnPrefix << "defval = <<_EnD_oF_dEf_TeXt_" << endl
192             << a->defval << endl << "_EnD_oF_dEf_TeXt_;" << endl;
193         }
194         if (defArg) ++defAli;
195         t << "      }; /*" << fcnPrefix << "-param */" << endl;
196       }
197     }
198     delete declAl;
199   }
200   else if (  md->memberType()==MemberType_Define
201       && md->argsString()!=0)
202   {
203     ArgumentListIterator ali(*md->argumentList());
204     Argument *a;
205     QCString defPrefix = "  " + memPrefix + "def-";
206
207     for (ali.toFirst();(a=ali.current());++ali)
208     {
209       t << memPrefix << "param  = {" << endl;
210       t << defPrefix << "name = '" << a->type << "';" << endl;
211       t << "      }; /*" << defPrefix << "-param */" << endl;
212     }
213   }
214
215   if (!md->initializer().isEmpty())
216   {
217     t << memPrefix << "initializer = <<_EnD_oF_dEf_TeXt_" << endl
218       << md->initializer() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
219   }
220   // TODO: exceptions, const volatile
221   if (md->memberType()==MemberType_Enumeration) // enum
222   {
223     MemberList *enumList = md->enumFieldList();
224     if (enumList!=0)
225     {
226       MemberListIterator emli(*enumList);
227       MemberDef *emd;
228       for (emli.toFirst();(emd=emli.current());++emli)
229       {
230         t << memPrefix << "enum = { enum-name = " << emd->name() << ';';
231         if (!emd->initializer().isEmpty())
232         {
233           t << " enum-value = ";
234           writeDEFString(t,emd->initializer());
235           t << ';';
236         }
237         t << " };" << endl;
238       }
239     }
240   }
241
242   t << memPrefix << "desc-file = '" << md->getDefFileName() << "';" << endl;
243   t << memPrefix << "desc-line = '" << md->getDefLine()     << "';" << endl;
244   t << memPrefix << "briefdesc =    <<_EnD_oF_dEf_TeXt_"    << endl
245     << md->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
246   t << memPrefix << "documentation = <<_EnD_oF_dEf_TeXt_"   << endl
247     << md->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
248
249   //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers());
250
251   MemberSDict *mdict = md->getReferencesMembers();
252   if (mdict)
253   {
254     MemberSDict::Iterator mdi(*mdict);
255     MemberDef *rmd;
256     QCString refPrefix = "  " + memPrefix + "ref-";
257
258     for (mdi.toFirst();(rmd=mdi.current());++mdi)
259     {
260       if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
261       {
262         t << memPrefix << "referenceto = {" << endl;
263         t << refPrefix << "id = '"
264           << rmd->getBodyDef()->getOutputFileBase()
265           << "_1"   // encoded `:' character (see util.cpp:convertNameToFile)
266           << rmd->anchor() << "';" << endl;
267
268         t << refPrefix << "line = '"
269           << rmd->getStartBodyLine() << "';" << endl;
270
271         QCString scope = rmd->getScopeString();
272         QCString name = rmd->name();
273         if (!scope.isEmpty() && scope!=def->name())
274         {
275           name.prepend(scope+"::");
276         }
277
278         t << refPrefix << "name = ";
279         writeDEFString(t,name);
280         t << ';' << endl << "    };" << endl;
281       }
282     } /* for (mdi.toFirst...) */
283   }
284   mdict = md->getReferencedByMembers();
285   if (mdict)
286   {
287     MemberSDict::Iterator mdi(*mdict);
288     MemberDef *rmd;
289     QCString refPrefix = "  " + memPrefix + "ref-";
290
291     for (mdi.toFirst();(rmd=mdi.current());++mdi)
292     {
293       if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
294       {
295         t << memPrefix << "referenceby = {" << endl;
296         t << refPrefix << "id = '"
297           << rmd->getBodyDef()->getOutputFileBase()
298           << "_1"   // encoded `:' character (see util.cpp:convertNameToFile)
299           << rmd->anchor() << "';" << endl;
300
301         t << refPrefix << "line = '"
302           << rmd->getStartBodyLine() << "';" << endl;
303
304         QCString scope = rmd->getScopeString();
305         QCString name = rmd->name();
306         if (!scope.isEmpty() && scope!=def->name())
307         {
308           name.prepend(scope+"::");
309         }
310
311         t << refPrefix << "name = ";
312         writeDEFString(t,name);
313         t << ';' << endl << "    };" << endl;
314       }
315     } /* for (mdi.toFirst...) */
316   }
317
318   t << "    }; /* " << Prefix << "-member */" << endl;
319 }
320
321
322 void generateDEFClassSection(ClassDef *cd,
323     FTextStream &t,
324     MemberList *ml,
325     const char *kind)
326 {
327   if (cd && ml && ml->count()>0)
328   {
329     t << "  cp-section = {" << endl;
330     t << "    sec-kind = '" << kind << "';" << endl;
331
332     MemberListIterator mli(*ml);
333     MemberDef *md;
334     for (mli.toFirst();(md=mli.current());++mli)
335     {
336       generateDEFForMember(md,t,cd,"sec");
337     }
338     t << "  }; /* cp-section */" << endl;
339   }
340 }
341
342 void generateDEFForClass(ClassDef *cd,FTextStream &t)
343 {
344   // + brief description
345   // + detailed description
346   // - template arguments
347   // - include files
348   // + inheritance diagram
349   // + list of direct super classes
350   // + list of direct sub classes
351   // + collaboration diagram
352   // - list of all members
353   // + user defined member sections
354   // + standard member sections
355   // + detailed member documentation
356   // - examples
357
358   if (cd->isReference()) return; // skip external references.
359   if (cd->name().find('@')!=-1) return; // skip anonymous compounds.
360   if (cd->templateMaster()!=0) return; // skip generated template instances.
361
362   t << cd->compoundTypeString() << " = {" << endl;
363   t << "  cp-id     = '" << cd->getOutputFileBase() << "';" << endl;
364   t << "  cp-name   = '" << cd->name() << "';" << endl;
365
366   if (cd->baseClasses())
367   {
368     BaseClassListIterator bcli(*cd->baseClasses());
369     BaseClassDef *bcd;
370     for (bcli.toFirst();(bcd=bcli.current());++bcli)
371     {
372       t << "  cp-ref     = {" << endl << "    ref-type = base;" << endl;
373       t << "    ref-id   = '"
374         << bcd->classDef->getOutputFileBase() << "';" << endl;
375       t << "    ref-prot = ";
376       switch (bcd->prot)
377       {
378         case Public:    t << "public;"    << endl; break;
379         case Package: // package scope is not possible
380         case Protected: t << "protected;" << endl; break;
381         case Private:   t << "private;"   << endl; break;
382       }
383       t << "    ref-virt = ";
384       switch(bcd->virt)
385       {
386         case Normal:  t << "non-virtual;";  break;
387         case Virtual: t << "virtual;";      break;
388         case Pure:    t << "pure-virtual;"; break;
389       }
390       t << endl << "  };" << endl;
391     }
392   }
393
394   if (cd->subClasses())
395   {
396     BaseClassListIterator bcli(*cd->subClasses());
397     BaseClassDef *bcd;
398     for (bcli.toFirst();(bcd=bcli.current());++bcli)
399     {
400       t << "  cp-ref     = {" << endl << "    ref-type = derived;" << endl;
401       t << "    ref-id   = '"
402         << bcd->classDef->getOutputFileBase() << "';" << endl;
403       t << "    ref-prot = ";
404       switch (bcd->prot)
405       {
406         case Public:    t << "public;"    << endl; break;
407         case Package: // packet scope is not possible!
408         case Protected: t << "protected;" << endl; break;
409         case Private:   t << "private;"   << endl; break;
410       }
411       t << "    ref-virt = ";
412       switch(bcd->virt)
413       {
414         case Normal:  t << "non-virtual;";  break;
415         case Virtual: t << "virtual;";      break;
416         case Pure:    t << "pure-virtual;"; break;
417       }
418       t << endl << "  };" << endl;
419     }
420   }
421
422   int numMembers = 0;
423   QListIterator<MemberList> mli(cd->getMemberLists());
424   MemberList *ml;
425   for (mli.toFirst();(ml=mli.current());++mli)
426   {
427     if ((ml->listType()&MemberListType_detailedLists)==0)
428     {
429       numMembers+=ml->count();
430     }
431   }
432   if (numMembers>0)
433   {
434     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubTypes),"public-type");
435     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_interfaces),"interfaces");
436     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_services),"services");
437     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubMethods),"public-func");
438     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubAttribs),"public-attrib");
439     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubSlots),"public-slot");
440     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_signals),"signal");
441     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_dcopMethods),"dcop-func");
442     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_properties),"property");
443     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubStaticMethods),"public-static-func");
444     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_pubStaticAttribs),"public-static-attrib");
445     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proTypes),"protected-type");
446     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proMethods),"protected-func");
447     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proAttribs),"protected-attrib");
448     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proSlots),"protected-slot");
449     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proStaticMethods),"protected-static-func");
450     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_proStaticAttribs),"protected-static-attrib");
451     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priTypes),"private-type");
452     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priMethods),"private-func");
453     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priAttribs),"private-attrib");
454     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priSlots),"private-slot");
455     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priStaticMethods),"private-static-func");
456     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_priStaticAttribs),"private-static-attrib");
457     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_friends),"signal");
458     generateDEFClassSection(cd,t,cd->getMemberList(MemberListType_related),"related");
459   }
460
461   t << "  cp-filename  = '" << cd->getDefFileName() << "';" << endl;
462   t << "  cp-fileline  = '" << cd->getDefLine()     << "';" << endl;
463   t << "  cp-briefdesc = <<_EnD_oF_dEf_TeXt_" << endl
464     << cd->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
465
466   t << "  cp-documentation = <<_EnD_oF_dEf_TeXt_" << endl
467     << cd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
468
469   DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
470   if (!inheritanceGraph.isTrivial())
471   {
472     t << "  cp-inheritancegraph = <<_EnD_oF_dEf_TeXt_" << endl;
473     inheritanceGraph.writeDEF(t);
474     t << endl << "_EnD_oF_dEf_TeXt_;" << endl;
475   }
476   DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
477   if (!collaborationGraph.isTrivial())
478   {
479     t << "  cp-collaborationgraph = <<_EnD_oF_dEf_TeXt_" << endl;
480     collaborationGraph.writeDEF(t);
481     t << endl << "_EnD_oF_dEf_TeXt_;" << endl;
482   }
483   t << "}; /* " <<  cd->compoundTypeString() << " */" << endl;
484 }
485
486 void generateDEFSection(Definition *d,
487     FTextStream &t,
488     MemberList *ml,
489     const char *kind)
490 {
491   if (ml && ml->count()>0)
492   {
493     t << "    " << kind << " = {" << endl;
494     MemberListIterator mli(*ml);
495     MemberDef *md;
496     for (mli.toFirst();(md=mli.current());++mli)
497     {
498       generateDEFForMember(md,t,d,kind);
499     }
500     t << "    };" << endl;
501   }
502 }
503
504 void generateDEFForNamespace(NamespaceDef *nd,FTextStream &t)
505 {
506   if (nd->isReference()) return; // skip external references
507   t << "  namespace = {" << endl;
508   t << "    ns-id   = '" << nd->getOutputFileBase() << "';" << endl;
509   t << "    ns-name = ";
510   writeDEFString(t,nd->name());
511   t << ';' << endl;
512
513   generateDEFSection(nd,t,nd->getMemberList(MemberListType_decDefineMembers),"define");
514   generateDEFSection(nd,t,nd->getMemberList(MemberListType_decProtoMembers),"prototype");
515   generateDEFSection(nd,t,nd->getMemberList(MemberListType_decTypedefMembers),"typedef");
516   generateDEFSection(nd,t,nd->getMemberList(MemberListType_decSequenceMembers),"sequence");
517   generateDEFSection(nd,t,nd->getMemberList(MemberListType_decDictionaryMembers),"dictionary");
518   generateDEFSection(nd,t,nd->getMemberList(MemberListType_decEnumMembers),"enum");
519   generateDEFSection(nd,t,nd->getMemberList(MemberListType_decFuncMembers),"func");
520   generateDEFSection(nd,t,nd->getMemberList(MemberListType_decVarMembers),"var");
521
522   t << "  ns-filename  = '" << nd->getDefFileName() << "';" << endl;
523   t << "  ns-fileline  = '" << nd->getDefLine()     << "';" << endl;
524   t << "  ns-briefdesc = <<_EnD_oF_dEf_TeXt_" << endl
525     << nd->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
526
527   t << "  ns-documentation = <<_EnD_oF_dEf_TeXt_" << endl
528     << nd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
529   t << "  };" << endl;
530 }
531
532 void generateDEFForFile(FileDef *fd,FTextStream &t)
533 {
534   if (fd->isReference()) return; // skip external references
535
536   t << "file = {" << endl;
537   t << "  file-id   = '" << fd->getOutputFileBase() << "';" << endl;
538   t << "  file-name = ";
539   writeDEFString(t,fd->name());
540   t << ';' << endl;
541
542   generateDEFSection(fd,t,fd->getMemberList(MemberListType_decDefineMembers),"define");
543   generateDEFSection(fd,t,fd->getMemberList(MemberListType_decProtoMembers),"prototype");
544   generateDEFSection(fd,t,fd->getMemberList(MemberListType_decTypedefMembers),"typedef");
545   generateDEFSection(fd,t,fd->getMemberList(MemberListType_decSequenceMembers),"sequence");
546   generateDEFSection(fd,t,fd->getMemberList(MemberListType_decDictionaryMembers),"dictionary");
547   generateDEFSection(fd,t,fd->getMemberList(MemberListType_decEnumMembers),"enum");
548   generateDEFSection(fd,t,fd->getMemberList(MemberListType_decFuncMembers),"func");
549   generateDEFSection(fd,t,fd->getMemberList(MemberListType_decVarMembers),"var");
550
551   t << "  file-full-name  = '" << fd->getDefFileName() << "';" << endl;
552   t << "  file-first-line = '" << fd->getDefLine()     << "';" << endl;
553
554   t << "  file-briefdesc  = <<_EnD_oF_dEf_TeXt_" << endl
555     << fd->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
556
557   t << "  file-documentation = <<_EnD_oF_dEf_TeXt_" << endl
558     << fd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
559
560   t << "}; /* file */" << endl;
561 }
562
563
564 void generateDEF()
565 {
566   QCString outputDirectory = Config_getString(OUTPUT_DIRECTORY);
567   if (outputDirectory.isEmpty())
568   {
569     outputDirectory=QDir::currentDirPath().utf8();
570   }
571   else
572   {
573     QDir dir(outputDirectory);
574     if (!dir.exists())
575     {
576       dir.setPath(QDir::currentDirPath());
577       if (!dir.mkdir(outputDirectory))
578       {
579         err("tag OUTPUT_DIRECTORY: Output directory `%s' does not "
580             "exist and cannot be created\n",outputDirectory.data());
581         exit(1);
582       }
583       else
584       {
585         msg("Notice: Output directory `%s' does not exist. "
586             "I have created it for you.\n", outputDirectory.data());
587       }
588       dir.cd(outputDirectory);
589     }
590     outputDirectory=dir.absPath().utf8();
591   }
592
593   QDir dir(outputDirectory);
594   if (!dir.exists())
595   {
596     dir.setPath(QDir::currentDirPath());
597     if (!dir.mkdir(outputDirectory))
598     {
599       err("Cannot create directory %s\n",outputDirectory.data());
600       return;
601     }
602   }
603   QDir defDir(outputDirectory+"/def");
604   if (!defDir.exists() && !defDir.mkdir(outputDirectory+"/def"))
605   {
606     err("Could not create def directory in %s\n",outputDirectory.data());
607     return;
608   }
609
610   QCString fileName=outputDirectory+"/def/doxygen.def";
611   QFile f(fileName);
612   if (!f.open(IO_WriteOnly))
613   {
614     err("Cannot open file %s for writing!\n",fileName.data());
615     return;
616   }
617   FTextStream t(&f);
618   t << "AutoGen Definitions dummy;" << endl;
619
620   if (Doxygen::classSDict->count()+Doxygen::inputNameList->count()>0)
621   {
622     ClassSDict::Iterator cli(*Doxygen::classSDict);
623     ClassDef *cd;
624     for (cli.toFirst();(cd=cli.current());++cli)
625     {
626       generateDEFForClass(cd,t);
627     }
628     FileNameListIterator fnli(*Doxygen::inputNameList);
629     FileName *fn;
630     for (;(fn=fnli.current());++fnli)
631     {
632       FileNameIterator fni(*fn);
633       FileDef *fd;
634       for (;(fd=fni.current());++fni)
635       {
636         generateDEFForFile(fd,t);
637       }
638     }
639   }
640   else
641   {
642     t << "dummy_value = true;" << endl;
643   }
644 }