Fix for UBSan build
[platform/upstream/doxygen.git] / src / defgen.cpp
1 /******************************************************************************
2  *
3  * $Id: def.cpp,v 1.2 2001/01/01 10:15:18 root Exp $
4  *
5  *
6  * Copyright (C) 1997-2012 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 "qtbc.h"
22 #include "defgen.h"
23 #include "doxygen.h"
24 #include "message.h"
25 #include "config.h"
26 #include "classlist.h"
27 #include "util.h"
28 #include "defargs.h"
29 #include "outputgen.h"
30 #include "dot.h"
31 #include "arguments.h"
32
33 #include <qdir.h>
34 #include <qfile.h>
35 #include <qtextstream.h>
36
37 #define DEF_DB(x)
38
39 inline void writeDEFString(FTextStream &t,const char *s)
40 {
41   const char* p=s;
42   char c;
43
44   t << '\'';
45   while ((c = *(p++)))
46   {
47     if (c == '\'')
48       t << '\\';
49     t << c;
50   }
51   t << '\'';
52 }
53
54 void generateDEFForMember(MemberDef *md,
55     FTextStream &t,
56     Definition *def,
57     const char* Prefix)
58 {
59   QCString memPrefix;
60
61   // + declaration
62   // - reimplements
63   // - reimplementedBy
64   // - exceptions
65   // - const/volatile specifiers
66   // - examples
67   // + source definition
68   // - source references
69   // - source referenced by
70   // - include code 
71
72   if (md->memberType()==MemberDef::EnumValue) return;
73
74   QCString scopeName;
75   if (md->getClassDef()) 
76     scopeName=md->getClassDef()->name();
77   else if (md->getNamespaceDef()) 
78     scopeName=md->getNamespaceDef()->name();
79
80   t << "    " << Prefix << "-member = {" << endl;
81   memPrefix = "      ";
82   memPrefix.append( Prefix );
83   memPrefix.append( "-mem-" );
84
85   QCString memType;
86   bool isFunc=FALSE;
87   switch (md->memberType())
88   {
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;
101   }
102
103   t << memPrefix << "kind = '" << memType << "';" << endl;
104   t << memPrefix << "id   = '"
105     << md->getOutputFileBase() << "_1" << md->anchor()
106     << "';" << endl;
107
108   t << memPrefix << "virt = ";
109   switch (md->virtualness())
110   {
111     case Normal:  t << "normal;"       << endl; break;
112     case Virtual: t << "virtual;"      << endl; break;
113     case Pure:    t << "pure-virtual;" << endl; break;
114     default: ASSERT(0);
115   }
116
117   t << memPrefix << "prot = ";
118   switch(md->protection())
119   {
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;
124   }
125
126   if (md->memberType()!=MemberDef::Define &&
127       md->memberType()!=MemberDef::Enumeration
128      )
129   {
130     QCString typeStr = replaceAnonymousScopes(md->typeString());
131     t << memPrefix << "type = <<_EnD_oF_dEf_TeXt_" << endl << typeStr << endl
132       << "_EnD_oF_dEf_TeXt_;" << endl;
133   }
134
135   t << memPrefix << "name = '" << md->name() << "';" << endl;
136
137   if (isFunc) //function
138   {
139     ArgumentList *declAl = new ArgumentList;
140     LockingPtr<ArgumentList> defAl = md->argumentList();
141     stringToArgumentList(md->argsString(),declAl);
142     QCString fcnPrefix = "  " + memPrefix + "param-";
143
144     if (declAl->count()>0)
145     {
146       ArgumentListIterator declAli(*declAl);
147       ArgumentListIterator defAli(*defAl);
148       Argument *a;
149       for (declAli.toFirst();(a=declAli.current());++declAli)
150       {
151         Argument *defArg = defAli.current();
152         t << memPrefix << "param = {" << endl;
153         if (!a->attrib.isEmpty())
154         {
155           t << fcnPrefix << "attributes = ";
156           writeDEFString(t,a->attrib);
157           t << ';' << endl;
158         }
159         if (!a->type.isEmpty())
160         {
161           t << fcnPrefix << "type = <<_EnD_oF_dEf_TeXt_" << endl
162             << a->type << endl << "_EnD_oF_dEf_TeXt_;" << endl;
163         }
164         if (!a->name.isEmpty())
165         {
166           t << fcnPrefix << "declname = ";
167           writeDEFString(t,a->name);
168           t << ';' << endl;
169         }
170         if (defArg && !defArg->name.isEmpty() && defArg->name!=a->name)
171         {
172           t << fcnPrefix << "defname = ";
173           writeDEFString(t,defArg->name);
174           t << ';' << endl;
175         }
176         if (!a->array.isEmpty())
177         {
178           t << fcnPrefix << "array = ";
179           writeDEFString(t,a->array); 
180           t << ';' << endl;
181         }
182         if (!a->defval.isEmpty())
183         {
184           t << fcnPrefix << "defval = <<_EnD_oF_dEf_TeXt_" << endl
185             << a->defval << endl << "_EnD_oF_dEf_TeXt_;" << endl;
186         }
187         if (defArg) ++defAli;
188         t << "      }; /*" << fcnPrefix << "-param */" << endl;
189       }
190     }
191     delete declAl;
192   }
193   else if (  md->memberType()==MemberDef::Define
194       && md->argsString()!=0)
195   {
196     ArgumentListIterator ali(*md->argumentList());
197     Argument *a;
198     QCString defPrefix = "  " + memPrefix + "def-";
199
200     for (ali.toFirst();(a=ali.current());++ali)
201     {
202       t << memPrefix << "param  = {" << endl;
203       t << defPrefix << "name = '" << a->type << "';" << endl;
204       t << "      }; /*" << defPrefix << "-param */" << endl;
205     }
206   }
207
208   if (!md->initializer().isEmpty())
209   {
210     t << memPrefix << "initializer = <<_EnD_oF_dEf_TeXt_" << endl
211       << md->initializer() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
212   }
213   // TODO: exceptions, const volatile
214   if (md->memberType()==MemberDef::Enumeration) // enum
215   {
216     LockingPtr<MemberList> enumList = md->enumFieldList();
217     if (enumList!=0)
218     {
219       MemberListIterator emli(*enumList);
220       MemberDef *emd;
221       for (emli.toFirst();(emd=emli.current());++emli)
222       {
223         t << memPrefix << "enum = { enum-name = " << emd->name() << ';';
224         if (!emd->initializer().isEmpty())
225         {
226           t << " enum-value = ";
227           writeDEFString(t,emd->initializer());
228           t << ';';
229         }
230         t << " };" << endl;
231       }
232     }
233   }
234
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;
241
242   //printf("md->getReferencesMembers()=%p\n",md->getReferencesMembers());
243
244   LockingPtr<MemberSDict> mdict = md->getReferencesMembers();
245   if (!mdict.isNull())
246   {
247     MemberSDict::Iterator mdi(*mdict);
248     MemberDef *rmd;
249     QCString refPrefix = "  " + memPrefix + "ref-";
250
251     for (mdi.toFirst();(rmd=mdi.current());++mdi)
252     {
253       if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
254       {
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;
260
261         t << refPrefix << "line = '"
262           << rmd->getStartBodyLine() << "';" << endl;
263
264         QCString scope = rmd->getScopeString();
265         QCString name = rmd->name();
266         if (!scope.isEmpty() && scope!=def->name())
267         {
268           name.prepend(scope+"::");
269         }
270
271         t << refPrefix << "name = ";
272         writeDEFString(t,name);
273         t << ';' << endl << "    };" << endl;
274       }
275     } /* for (mdi.toFirst...) */
276   }
277   mdict = md->getReferencedByMembers();
278   if (!mdict.isNull())
279   {
280     MemberSDict::Iterator mdi(*mdict);
281     MemberDef *rmd;
282     QCString refPrefix = "  " + memPrefix + "ref-";
283
284     for (mdi.toFirst();(rmd=mdi.current());++mdi)
285     {
286       if (rmd->getStartBodyLine()!=-1 && rmd->getBodyDef())
287       {
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;
293
294         t << refPrefix << "line = '"
295           << rmd->getStartBodyLine() << "';" << endl;
296
297         QCString scope = rmd->getScopeString();
298         QCString name = rmd->name();
299         if (!scope.isEmpty() && scope!=def->name())
300         {
301           name.prepend(scope+"::");
302         }
303
304         t << refPrefix << "name = ";
305         writeDEFString(t,name);
306         t << ';' << endl << "    };" << endl;
307       }
308     } /* for (mdi.toFirst...) */
309   }
310
311   t << "    }; /* " << Prefix << "-member */" << endl;
312 }
313
314
315 void generateDEFClassSection(ClassDef *cd,
316     FTextStream &t,
317     MemberList *ml,
318     const char *kind)
319 {
320   if (cd && ml && ml->count()>0)
321   {
322     t << "  cp-section = {" << endl;
323     t << "    sec-kind = '" << kind << "';" << endl;
324
325     MemberListIterator mli(*ml);
326     MemberDef *md;
327     for (mli.toFirst();(md=mli.current());++mli)
328     {
329       generateDEFForMember(md,t,cd,"sec");
330     }
331     t << "  }; /* cp-section */" << endl;
332   }
333 }
334
335 void generateDEFForClass(ClassDef *cd,FTextStream &t)
336 {
337   // + brief description
338   // + detailed description
339   // - template arguments
340   // - include files
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
349   // - examples
350
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.
354
355   t << cd->compoundTypeString() << " = {" << endl;
356   t << "  cp-id     = '" << cd->getOutputFileBase() << "';" << endl;
357   t << "  cp-name   = '" << cd->name() << "';" << endl;
358
359   if (cd->baseClasses())
360   {
361     BaseClassListIterator bcli(*cd->baseClasses());
362     BaseClassDef *bcd;
363     for (bcli.toFirst();(bcd=bcli.current());++bcli)
364     {
365       t << "  cp-ref     = {" << endl << "    ref-type = base;" << endl;
366       t << "    ref-id   = '"
367         << bcd->classDef->getOutputFileBase() << "';" << endl;
368       t << "    ref-prot = ";
369       switch (bcd->prot)
370       {
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;
375       }
376       t << "    ref-virt = ";
377       switch(bcd->virt)
378       {
379         case Normal:  t << "non-virtual;";  break;
380         case Virtual: t << "virtual;";      break;
381         case Pure:    t << "pure-virtual;"; break;
382       }
383       t << endl << "  };" << endl;
384     }
385   }
386
387   if (cd->subClasses())
388   {
389     BaseClassListIterator bcli(*cd->subClasses());
390     BaseClassDef *bcd;
391     for (bcli.toFirst();(bcd=bcli.current());++bcli)
392     {
393       t << "  cp-ref     = {" << endl << "    ref-type = derived;" << endl;
394       t << "    ref-id   = '"
395         << bcd->classDef->getOutputFileBase() << "';" << endl;
396       t << "    ref-prot = ";
397       switch (bcd->prot)
398       {
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;
403       }
404       t << "    ref-virt = ";
405       switch(bcd->virt)
406       {
407         case Normal:  t << "non-virtual;";  break;
408         case Virtual: t << "virtual;";      break;
409         case Pure:    t << "pure-virtual;"; break;
410       }
411       t << endl << "  };" << endl;
412     }
413   }
414
415   int numMembers = 0;
416   QListIterator<MemberList> mli(cd->getMemberLists());
417   MemberList *ml;
418   for (mli.toFirst();(ml=mli.current());++mli)
419   {
420     if ((ml->listType()&MemberList::detailedLists)==0)
421     {
422       numMembers+=ml->count();
423     }
424   }
425   if (numMembers>0)
426   {
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");
450   }
451
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;
456
457   t << "  cp-documentation = <<_EnD_oF_dEf_TeXt_" << endl
458     << cd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
459
460   DotClassGraph inheritanceGraph(cd,DotNode::Inheritance);
461   if (!inheritanceGraph.isTrivial())
462   {
463     t << "  cp-inheritancegraph = <<_EnD_oF_dEf_TeXt_" << endl;
464     inheritanceGraph.writeDEF(t);
465     t << endl << "_EnD_oF_dEf_TeXt_;" << endl;
466   }
467   DotClassGraph collaborationGraph(cd,DotNode::Collaboration);
468   if (!collaborationGraph.isTrivial())
469   {
470     t << "  cp-collaborationgraph = <<_EnD_oF_dEf_TeXt_" << endl;
471     collaborationGraph.writeDEF(t);
472     t << endl << "_EnD_oF_dEf_TeXt_;" << endl;
473   }
474   t << "}; /* " <<  cd->compoundTypeString() << " */" << endl;
475 }
476
477 void generateDEFSection(Definition *d,
478     FTextStream &t,
479     MemberList *ml,
480     const char *kind)
481 {
482   if (ml && ml->count()>0)
483   {
484     t << "    " << kind << " = {" << endl;
485     MemberListIterator mli(*ml);
486     MemberDef *md;
487     for (mli.toFirst();(md=mli.current());++mli)
488     {
489       generateDEFForMember(md,t,d,kind);
490     }
491     t << "    };" << endl;
492   }
493 }
494
495 void generateDEFForNamespace(NamespaceDef *nd,FTextStream &t)
496 {
497   if (nd->isReference()) return; // skip external references
498   t << "  namespace = {" << endl;
499   t << "    ns-id   = '" << nd->getOutputFileBase() << "';" << endl;
500   t << "    ns-name = ";
501   writeDEFString(t,nd->name());
502   t << ';' << endl;
503
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");
510
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;
515
516   t << "  ns-documentation = <<_EnD_oF_dEf_TeXt_" << endl
517     << nd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
518   t << "  };" << endl;
519 }
520
521 void generateDEFForFile(FileDef *fd,FTextStream &t)
522 {
523   if (fd->isReference()) return; // skip external references
524
525   t << "file = {" << endl;
526   t << "  file-id   = '" << fd->getOutputFileBase() << "';" << endl;
527   t << "  file-name = ";
528   writeDEFString(t,fd->name());
529   t << ';' << endl;
530
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");
537
538   t << "  file-full-name  = '" << fd->getDefFileName() << "';" << endl;
539   t << "  file-first-line = '" << fd->getDefLine()     << "';" << endl;
540
541   t << "  file-briefdesc  = <<_EnD_oF_dEf_TeXt_" << endl
542     << fd->briefDescription() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
543
544   t << "  file-documentation = <<_EnD_oF_dEf_TeXt_" << endl
545     << fd->documentation() << endl << "_EnD_oF_dEf_TeXt_;" << endl;
546
547   t << "}; /* file */" << endl;
548 }
549
550
551 void generateDEF()
552 {
553   QCString outputDirectory = Config_getString("OUTPUT_DIRECTORY");
554   if (outputDirectory.isEmpty())
555   {
556     outputDirectory=QDir::currentDirPath().utf8();
557   }
558   else
559   {
560     QDir dir(outputDirectory);
561     if (!dir.exists())
562     {
563       dir.setPath(QDir::currentDirPath());
564       if (!dir.mkdir(outputDirectory))
565       {
566         err("error: tag OUTPUT_DIRECTORY: Output directory `%s' does not "
567             "exist and cannot be created\n",outputDirectory.data());
568         exit(1);
569       }
570       else if (!Config_getBool("QUIET"))
571       {
572         err("notice: Output directory `%s' does not exist. "
573             "I have created it for you.\n", outputDirectory.data());
574       }
575       dir.cd(outputDirectory);
576     }
577     outputDirectory=dir.absPath().utf8();
578   }
579
580   QDir dir(outputDirectory);
581   if (!dir.exists())
582   {
583     dir.setPath(QDir::currentDirPath());
584     if (!dir.mkdir(outputDirectory))
585     {
586       err("Cannot create directory %s\n",outputDirectory.data());
587       return;
588     }
589   }
590   QDir defDir(outputDirectory+"/def");
591   if (!defDir.exists() && !defDir.mkdir(outputDirectory+"/def"))
592   {
593     err("Could not create def directory in %s\n",outputDirectory.data());
594     return;
595   }
596
597   QCString fileName=outputDirectory+"/def/doxygen.def";
598   QFile f(fileName);
599   if (!f.open(IO_WriteOnly))
600   {
601     err("Cannot open file %s for writing!\n",fileName.data());
602     return;
603   }
604   FTextStream t(&f);
605   t << "AutoGen Definitions dummy;" << endl;
606
607   if (Doxygen::classSDict->count()+Doxygen::inputNameList->count()>0)
608   {
609     ClassSDict::Iterator cli(*Doxygen::classSDict);
610     ClassDef *cd;
611     for (cli.toFirst();(cd=cli.current());++cli)
612     {
613       generateDEFForClass(cd,t);
614     }
615     FileNameListIterator fnli(*Doxygen::inputNameList);
616     FileName *fn;
617     for (;(fn=fnli.current());++fnli)
618     {
619       FileNameIterator fni(*fn);
620       FileDef *fd;
621       for (;(fd=fni.current());++fni)
622       {
623         generateDEFForFile(fd,t);
624       }
625     }
626   }
627   else
628   {
629     t << "dummy_value = true;" << endl;
630   }
631 }