Imported Upstream version 1.8.15
[platform/upstream/doxygen.git] / src / entry.cpp
1 /******************************************************************************
2  *
3  * 
4  *
5  * Copyright (C) 1997-2015 by Dimitri van Heesch.
6  *
7  * Permission to use, copy, modify, and distribute this software and its
8  * documentation under the terms of the GNU General Public License is hereby 
9  * granted. No representations are made about the suitability of this software 
10  * for any purpose. It is provided "as is" without express or implied warranty.
11  * See the GNU General Public License for more details.
12  *
13  * Documents produced by Doxygen are derivative works derived from the
14  * input used in their production; they are not affected by this license.
15  *
16  */
17
18 #include <stdlib.h>
19 #include <qfile.h>
20 #include "entry.h"
21 #include "marshal.h"
22 #include "util.h"
23 #include "section.h"
24 #include "doxygen.h"
25 #include "filestorage.h"
26 #include "arguments.h"
27 #include "config.h"
28 //------------------------------------------------------------------
29
30 #define HEADER ('D'<<24)+('O'<<16)+('X'<<8)+'!'
31
32 //------------------------------------------------------------------
33
34 int Entry::num=0;
35
36 Entry::Entry()
37 {
38   //printf("Entry::Entry(%p)\n",this);
39   num++;
40   m_parent=0;
41   section = EMPTY_SEC;
42   m_sublist = new QList<Entry>;
43   m_sublist->setAutoDelete(TRUE);
44   extends = new QList<BaseInfo>;
45   extends->setAutoDelete(TRUE);
46   groups = new QList<Grouping>;
47   groups->setAutoDelete(TRUE);
48   anchors = new QList<SectionInfo>; // Doxygen::sectionDict takes ownership of the items!
49   argList = new ArgumentList;
50   argList->setAutoDelete(TRUE);
51   //printf("Entry::Entry() tArgList=0\n");
52   tArgLists = 0;
53   typeConstr = 0;
54   mGrpId = -1;
55   tagInfo = 0;
56   sli = 0;
57   relatesType = Simple;
58   hidden = FALSE;
59   groupDocType = GROUPDOC_NORMAL;
60   reset();
61 }
62
63 Entry::Entry(const Entry &e)
64 {
65   //printf("Entry::Entry(%p):copy\n",this);
66   num++;
67   section     = e.section;
68   type        = e.type;
69   name        = e.name;
70   tagInfo     = e.tagInfo;
71   protection  = e.protection;
72   mtype       = e.mtype;
73   spec        = e.spec;
74   initLines   = e.initLines;
75   stat        = e.stat;
76   localToc    = e.localToc;
77   explicitExternal = e.explicitExternal;
78   proto       = e.proto;
79   subGrouping = e.subGrouping;
80   callGraph   = e.callGraph;
81   callerGraph = e.callerGraph;
82   referencedByRelation = e.referencedByRelation;
83   referencesRelation   = e.referencesRelation;
84   virt        = e.virt;
85   args        = e.args;
86   bitfields   = e.bitfields;
87   argList     = e.argList->deepCopy();
88   tArgLists = 0;
89   program     = e.program;
90   initializer = e.initializer;
91   includeFile = e.includeFile;
92   includeName = e.includeName;
93   doc         = e.doc;
94   docLine     = e.docLine;
95   docFile     = e.docFile;
96   brief       = e.brief;
97   briefLine   = e.briefLine;
98   briefFile   = e.briefFile;
99   inbodyDocs  = e.inbodyDocs;
100   inbodyLine  = e.inbodyLine;
101   inbodyFile  = e.inbodyFile;
102   relates     = e.relates;
103   relatesType = e.relatesType;
104   read        = e.read;
105   write       = e.write;
106   inside      = e.inside;
107   exception   = e.exception;
108   typeConstr  = 0;
109   bodyLine    = e.bodyLine;
110   endBodyLine = e.endBodyLine;
111   mGrpId      = e.mGrpId;
112   extends     = new QList<BaseInfo>;
113   extends->setAutoDelete(TRUE);
114   groups      = new QList<Grouping>;
115   groups->setAutoDelete(TRUE);
116   anchors     = new QList<SectionInfo>;
117   fileName    = e.fileName;
118   startLine   = e.startLine;
119   startColumn = e.startColumn;
120   if (e.sli)
121   {
122     sli = new QList<ListItemInfo>;
123     sli->setAutoDelete(TRUE);
124     QListIterator<ListItemInfo> slii(*e.sli);
125     ListItemInfo *ili;
126     for (slii.toFirst();(ili=slii.current());++slii)
127     {
128       sli->append(new ListItemInfo(*ili));
129     }
130   }
131   else
132   {
133     sli=0;
134   }
135   lang        = e.lang;
136   hidden      = e.hidden;
137   artificial  = e.artificial;
138   groupDocType = e.groupDocType;
139   id          = e.id;
140
141   m_parent    = e.m_parent;
142   m_sublist   = new QList<Entry>;
143   m_sublist->setAutoDelete(TRUE);
144
145   // deep copy of the child entry list
146   QListIterator<Entry> eli(*e.m_sublist);
147   Entry *cur;
148   for (;(cur=eli.current());++eli)
149   {
150     m_sublist->append(new Entry(*cur));
151   }
152   
153   // deep copy base class list
154   QListIterator<BaseInfo> bli(*e.extends);
155   BaseInfo *bi;
156   for (;(bi=bli.current());++bli)
157   {
158     extends->append(new BaseInfo(*bi));
159   }
160   
161   // deep copy group list
162   QListIterator<Grouping> gli(*e.groups);
163   Grouping *g;
164   for (;(g=gli.current());++gli)
165   {
166     groups->append(new Grouping(*g));
167   }
168   
169   QListIterator<SectionInfo> sli2(*e.anchors);
170   SectionInfo *s;
171   for (;(s=sli2.current());++sli2)
172   {
173     anchors->append(s); // shallow copy, object are owned by Doxygen::sectionDict
174   }
175
176   // deep copy type constraint list
177   if (e.typeConstr)
178   {
179     typeConstr  = e.typeConstr->deepCopy();
180   }
181
182   // deep copy template argument lists
183   if (e.tArgLists)
184   {
185     tArgLists = copyArgumentLists(e.tArgLists);
186   }
187
188 }
189
190 Entry::~Entry()
191 {
192   //printf("Entry::~Entry(%p) num=%d\n",this,num);
193   //printf("Deleting entry %d name %s type %x children %d\n",
194   //       num,name.data(),section,sublist->count());
195   
196   delete m_sublist; // each element is now own by a EntryNav so we do no longer own
197                   // our children.
198   delete extends;
199   delete groups;
200   delete anchors;
201   delete argList;
202   delete tArgLists;
203   delete tagInfo;
204   delete typeConstr;
205   delete sli;
206   num--;
207 }
208
209 void Entry::addSubEntry(Entry *current)
210 {
211   //printf("Entry %d with name %s type 0x%x added to %s type 0x%x\n",
212   //    current->num,current->name.data(),current->section,
213   //    name.data(),section);
214   //printf("Entry::addSubEntry(%s:%p) to %s\n",current->name.data(),
215   //    current,name.data());
216   current->m_parent=this;
217   m_sublist->append(current);  
218 }
219
220 void Entry::reset()
221 {
222   static bool entryCallGraph   = Config_getBool(CALL_GRAPH);
223   static bool entryCallerGraph = Config_getBool(CALLER_GRAPH);
224   static bool entryReferencedByRelation = Config_getBool(REFERENCED_BY_RELATION);
225   static bool entryReferencesRelation   = Config_getBool(REFERENCES_RELATION);
226   //printf("Entry::reset()\n");
227   name.resize(0);
228   type.resize(0);
229   args.resize(0);
230   bitfields.resize(0);
231   exception.resize(0);
232   program.resize(0);
233   includeFile.resize(0);
234   includeName.resize(0);
235   doc.resize(0);
236   docFile.resize(0);
237   docLine=-1;
238   relates.resize(0);
239   relatesType=Simple;
240   brief.resize(0);
241   briefFile.resize(0);
242   briefLine=-1;
243   inbodyDocs.resize(0);
244   inbodyFile.resize(0);
245   inbodyLine=-1;
246   inside.resize(0);
247   fileName.resize(0);
248   initializer.resize(0);
249   initLines = -1;
250   startLine = 1;
251   startColumn = 1;
252   bodyLine = -1;
253   endBodyLine = -1;
254   mGrpId = -1;
255   callGraph   = entryCallGraph;
256   callerGraph = entryCallerGraph;
257   referencedByRelation = entryReferencedByRelation;
258   referencesRelation   = entryReferencesRelation;
259   section = EMPTY_SEC;
260   mtype   = Method;
261   virt    = Normal;
262   stat    = FALSE;
263   proto   = FALSE;
264   explicitExternal = FALSE;
265   spec  = 0;
266   lang = SrcLangExt_Unknown;
267   hidden = FALSE;
268   artificial = FALSE;
269   subGrouping = TRUE;
270   protection = Public;
271   groupDocType = GROUPDOC_NORMAL;
272   id.resize(0);
273   metaData.resize(0);
274   m_sublist->clear();
275   extends->clear();
276   groups->clear();
277   anchors->clear();
278   argList->clear();
279   if (tagInfo)    { delete tagInfo; tagInfo=0; }
280   if (tArgLists)  { delete tArgLists; tArgLists=0; }
281   if (sli)        { delete sli; sli=0; }
282   if (typeConstr) { delete typeConstr; typeConstr=0; }
283   //if (mtArgList) { delete mtArgList; mtArgList=0; }
284 }
285
286
287 int Entry::getSize()
288 {
289   return sizeof(Entry);
290 }
291
292 void Entry::createSubtreeIndex(EntryNav *nav,FileStorage *storage,FileDef *fd)
293 {
294   EntryNav *childNav = new EntryNav(nav,this);
295   nav->addChild(childNav);
296   childNav->setFileDef(fd);
297   childNav->saveEntry(this,storage);
298   if (m_sublist)
299   {
300     //printf("saveEntry: %d children\n",node->sublist->count());
301     QListIterator<Entry> eli(*m_sublist);
302     Entry *childNode;
303     for (eli.toFirst();(childNode=eli.current());++eli)
304     {
305       childNode->createSubtreeIndex(childNav,storage,fd);
306     }
307     //m_sublist->setAutoDelete(FALSE);
308     m_sublist->clear();
309   }
310 }
311
312 void Entry::createNavigationIndex(EntryNav *rootNav,FileStorage *storage,FileDef *fd)
313 {
314   createSubtreeIndex(rootNav,storage,fd);
315 }
316
317 void Entry::addSpecialListItem(const char *listName,int itemId)
318 {
319   if (sli==0)
320   {
321     sli = new QList<ListItemInfo>;
322     sli->setAutoDelete(TRUE);
323   }
324   ListItemInfo *ili=new ListItemInfo;
325   ili->type = listName;
326   ili->itemId = itemId;
327   sli->append(ili);
328 }
329
330 Entry *Entry::removeSubEntry(Entry *e)
331 {
332  int i = m_sublist->find(e);
333  return i!=-1 ? m_sublist->take(i) : 0;
334 }
335
336 //------------------------------------------------------------------
337
338
339 EntryNav::EntryNav(EntryNav *parent, Entry *e)
340              : m_parent(parent), m_subList(0), m_section(e->section), m_type(e->type),
341               m_name(e->name), m_fileDef(0), m_lang(e->lang), 
342               m_info(0), m_offset(-1), m_noLoad(FALSE) 
343 {
344   if (e->tagInfo)
345   {
346     m_tagInfo = new TagInfo;
347     m_tagInfo->tagName  = e->tagInfo->tagName;
348     m_tagInfo->fileName = e->tagInfo->fileName;
349     m_tagInfo->anchor   = e->tagInfo->anchor;
350     if (e->tagInfo)
351     {
352       //printf("tagInfo %p: tagName=%s fileName=%s anchor=%s\n",
353       //    e->tagInfo,
354       //    e->tagInfo->tagName.data(),
355       //    e->tagInfo->fileName.data(),
356       //    e->tagInfo->anchor.data());
357     }
358   }
359   else
360   {
361     m_tagInfo = 0;
362   }
363 }
364
365 EntryNav::~EntryNav()
366 {
367   delete m_subList;
368   delete m_info;
369   delete m_tagInfo;
370 }
371
372 void EntryNav::addChild(EntryNav *e)
373 {
374   if (m_subList==0) 
375   {
376     m_subList = new QList<EntryNav>;
377     m_subList->setAutoDelete(TRUE);
378   }
379   m_subList->append(e);
380 }
381
382 bool EntryNav::loadEntry(FileStorage *storage)
383 {
384   if (m_noLoad)
385   {
386     return TRUE;
387   }
388   if (m_offset==-1) 
389   {
390     //printf("offset not set!\n");
391     return FALSE;
392   }
393   //delete m_info;
394   //printf("EntryNav::loadEntry: new entry %p: %s\n",m_info,m_name.data());
395   //m_info->tagInfo = m_tagInfo;
396   //if (m_parent)
397   //{
398   //  m_info->parent = m_parent->m_info;
399   //}
400   //m_info->parent = 0;
401   //printf("load entry: seek to %llx\n",m_offset);
402   if (!storage->seek(m_offset)) 
403   {
404     //printf("seek failed!\n");
405     return FALSE;
406   }
407   if (m_info)  delete m_info;
408   m_info = unmarshalEntry(storage);
409   m_info->name = m_name;
410   m_info->type = m_type;
411   m_info->section = m_section;
412   return TRUE;
413 }
414
415 bool EntryNav::saveEntry(Entry *e,FileStorage *storage)
416 {
417   m_offset = storage->pos();
418   //printf("EntryNav::saveEntry offset=%llx\n",m_offset);
419   marshalEntry(storage,e);
420   return TRUE;
421 }
422
423 void EntryNav::releaseEntry()
424 {
425   if (!m_noLoad) 
426   { 
427     //printf("EntryNav::releaseEntry %p\n",m_info);
428     delete m_info; 
429     m_info=0; 
430   }
431 }
432
433 void EntryNav::setEntry(Entry *e) 
434
435   delete m_info;
436   m_info = e; 
437   //printf("EntryNav::setEntry %p\n",e);
438   m_noLoad=TRUE; 
439 }
440