Imported Upstream version 1.8.15
[platform/upstream/doxygen.git] / src / reflist.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 <stdio.h>
20 #include "reflist.h"
21 #include "util.h"
22 #include "ftextstream.h"
23 #include "definition.h"
24
25 /*! Create a list of items that are cross referenced with documentation blocks
26  *  @param listName String representing the name of the list.
27  *  @param pageTitle String representing the title of the list page.
28  *  @param secTitle String representing the title of the section.
29  */
30 RefList::RefList(const char *listName,
31                  const char *pageTitle,
32                  const char *secTitle
33                 )
34 {
35   m_itemList = 0;
36   m_dict = 0;
37   m_dictIterator = 0;
38   m_id = 0;
39   m_listName = listName;
40   m_fileName = convertNameToFile(listName,FALSE,TRUE);
41   m_pageTitle = pageTitle;
42   m_secTitle = secTitle;
43 }
44
45 /*! Destroy the todo list. Currently not called! */
46 RefList::~RefList()
47 {
48   delete m_dictIterator;
49   delete m_dict;
50   delete m_itemList;
51 }
52
53 /*! Adds a new item to the list.
54  *  \returns A unique id for this item.
55  */
56 int RefList::addRefItem()
57 {
58   if (m_dict==0)
59   {
60     m_dict = new QIntDict<RefItem>(1009);
61     m_dict->setAutoDelete(TRUE);
62     m_dictIterator = new QIntDictIterator<RefItem>(*m_dict);
63   }
64   RefItem *item = new RefItem;
65   m_id++;
66   m_dict->insert(m_id,item);
67   return m_id;
68 }
69
70 /*! Returns an item given it's id that is obtained with addRefItem()
71  *  \param itemId item's identifier.
72  *  \returns A pointer to the todo item's structure.
73  */
74 RefItem *RefList::getRefItem(int itemId)
75 {
76   return m_dict ? m_dict->find(itemId) : 0;
77 }
78
79 /*! Returns the first item in the dictionary or 0 if
80  *  non is available.
81  *  Items are not sorted.
82  */
83 RefItem *RefList::getFirstRefItem()
84 {
85   return m_dictIterator ? m_dictIterator->toFirst() : 0;
86 }
87
88 /*! Returns the next item in the dictionary or 0 if
89  *  we are at the end of the list.
90  *  Items are not sorted.
91  */
92 RefItem *RefList::getNextRefItem()
93 {
94   return m_dictIterator ? m_dictIterator->operator++() : 0;
95 }
96
97 /*! Returns the name of the list as set in the constructor. */
98 QCString RefList::listName() const
99 {
100   return m_listName;
101 }
102
103 QCString RefList::fileName() const
104 {
105   return m_fileName;
106 }
107
108 QCString RefList::pageTitle() const
109 {
110   return m_pageTitle;
111 }
112
113 QCString RefList::sectionTitle() const
114 {
115   return m_secTitle;
116 }
117
118 void RefList::insertIntoList(const char *key,RefItem *item)
119 {
120   if (m_itemList==0)
121   {
122     m_itemList = new SortedRefItems(1009);
123   }
124   RefItem *ri = m_itemList->find(key);
125   if (ri==0)
126   {
127     m_itemList->append(key,item);
128   }
129   else // item already added to the list (i.e. multiple item for the same
130        // entity)
131   {
132     if (ri!=item)
133     {
134       // We also have to check if the item is not already in the "extra" list
135       QListIterator<RefItem> li(ri->extraItems);
136       RefItem *extraItem;
137       bool doubleItem = false;
138       for (li.toFirst();(extraItem=li.current());++li)
139       {
140         if (item == extraItem) doubleItem = true;
141       }
142       if (!doubleItem) ri->extraItems.append(item);
143     }
144   }
145 }
146
147
148 void RefList::generatePage()
149 {
150   if (m_itemList==0) return;
151   m_itemList->sort();
152   SDict<RefItem>::Iterator it(*m_itemList);
153   RefItem *item;
154   QCString doc;
155   doc += "<dl class=\"reflist\">";
156   for (it.toFirst();(item=it.current());++it)
157   {
158     doc += " <dt>";
159     doc += "\n";
160     if (item->scope)
161     {
162       if (item->scope->name() != "<globalScope>")
163       {
164         doc += "\\_setscope ";
165         doc += item->scope->name();
166         doc += " ";
167       }
168     }
169     doc += item->prefix;
170     doc += " \\_internalref ";
171     doc += item->name;
172     // escape \'s in title, see issue #5901
173     QCString escapedTitle = substitute(item->title,"\\","\\\\");
174     if (item->scope &&
175         (item->scope->definitionType()==Definition::TypeClass ||
176          item->scope->definitionType()==Definition::TypeNamespace ||
177          item->scope->definitionType()==Definition::TypeMember ||
178          item->scope->definitionType()==Definition::TypePackage)
179        )
180     {
181       // prevent Obj-C names in e.g. todo list are seen as emoji
182       escapedTitle = substitute(escapedTitle,":","&Colon;");
183     }
184     doc += " \""+escapedTitle+"\" ";
185     // write declaration in case a function with arguments
186     if (!item->args.isEmpty()) 
187     {
188       // escape @'s in argument list, needed for Java annotations (see issue #6208)
189       // escape \'s in argument list (see issue #6533)
190       doc += substitute(substitute(item->args,"@","@@"),"\\","\\\\");
191     }
192     doc += "</dt><dd> \\anchor ";
193     doc += item->listAnchor;
194     doc += " ";
195     doc += item->text;
196     QListIterator<RefItem> li(item->extraItems);
197     RefItem *extraItem;
198     for (li.toFirst();(extraItem=li.current());++li)
199     {
200       doc += "<p> \\anchor ";
201       doc += extraItem->listAnchor;
202       doc += " ";
203       doc += extraItem->text;
204     }
205     doc += "</dd>";
206   }
207   doc += "</dl>\n";
208   //printf("generatePage('%s')\n",doc.data());
209   addRelatedPage(m_listName,m_pageTitle,doc,0,m_fileName,1,0,0,0);
210 }
211