Root/
Source at commit 1322 created 12 years 8 months ago. By meklort, Add doxygen to utils folder | |
---|---|
1 | /******************************************************************************␊ |
2 | *␊ |
3 | * $Id: $␊ |
4 | *␊ |
5 | *␊ |
6 | * Copyright (C) 1997-2006 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 | */␊ |
15 | ␊ |
16 | #include <qxml.h>␊ |
17 | #include "mainhandler.h"␊ |
18 | #include "compoundhandler.h"␊ |
19 | #include "sectionhandler.h"␊ |
20 | #include "graphhandler.h"␊ |
21 | #include "dochandler.h"␊ |
22 | #include "memberhandler.h"␊ |
23 | #include "debug.h"␊ |
24 | ␊ |
25 | ␊ |
26 | class ErrorHandler : public QXmlErrorHandler␊ |
27 | {␊ |
28 | public:␊ |
29 | virtual ~ErrorHandler() {}␊ |
30 | bool warning( const QXmlParseException & )␊ |
31 | {␊ |
32 | return FALSE;␊ |
33 | }␊ |
34 | bool error( const QXmlParseException & )␊ |
35 | {␊ |
36 | return FALSE;␊ |
37 | }␊ |
38 | bool fatalError( const QXmlParseException &exception )␊ |
39 | {␊ |
40 | debug(1,"Fatal error at line %d column %d: %s\n",␊ |
41 | exception.lineNumber(),exception.columnNumber(),␊ |
42 | exception.message().data());␊ |
43 | return FALSE;␊ |
44 | }␊ |
45 | QString errorString() { return ""; }␊ |
46 | ␊ |
47 | private:␊ |
48 | QString errorMsg;␊ |
49 | };␊ |
50 | ␊ |
51 | //--------------------------------------------------------------------------␊ |
52 | ␊ |
53 | class CompoundEntryIterator : public ICompoundIterator, ␊ |
54 | public QListIterator<CompoundEntry>␊ |
55 | {␊ |
56 | public:␊ |
57 | CompoundEntryIterator(const MainHandler *m,const QList<CompoundEntry> &list) :␊ |
58 | QListIterator<CompoundEntry>(list), m_mainHandler(m) {}␊ |
59 | virtual ~CompoundEntryIterator() {}␊ |
60 | ␊ |
61 | virtual void toFirst()␊ |
62 | { ␊ |
63 | QListIterator<CompoundEntry>::toFirst(); ␊ |
64 | }␊ |
65 | virtual void toLast()␊ |
66 | { ␊ |
67 | QListIterator<CompoundEntry>::toLast(); ␊ |
68 | }␊ |
69 | virtual void toNext()␊ |
70 | { ␊ |
71 | QListIterator<CompoundEntry>::operator++(); ␊ |
72 | }␊ |
73 | virtual void toPrev()␊ |
74 | { ␊ |
75 | QListIterator<CompoundEntry>::operator--(); ␊ |
76 | }␊ |
77 | virtual ICompound *current() const␊ |
78 | { ␊ |
79 | CompoundEntry *ch = QListIterator<CompoundEntry>::current(); ␊ |
80 | return ch ? m_mainHandler->compoundById(ch->id) : 0;␊ |
81 | }␊ |
82 | virtual void release()␊ |
83 | { delete this; }␊ |
84 | ␊ |
85 | private:␊ |
86 | const MainHandler *m_mainHandler;␊ |
87 | };␊ |
88 | ␊ |
89 | //--------------------------------------------------------------------------␊ |
90 | ␊ |
91 | MainHandler::MainHandler() : m_compoundDict(2999), m_compoundNameDict(2999),␊ |
92 | m_memberDict(12251), m_memberNameDict(12251),␊ |
93 | m_compoundsLoaded(1009)␊ |
94 | {␊ |
95 | m_compounds.setAutoDelete(TRUE);␊ |
96 | m_memberNameDict.setAutoDelete(TRUE);␊ |
97 | addStartHandler("doxygenindex"); ␊ |
98 | addEndHandler("doxygenindex");␊ |
99 | addStartHandler("compound",this,&MainHandler::startCompound);␊ |
100 | addEndHandler("compound");␊ |
101 | addStartHandler("member",this,&MainHandler::startMember);␊ |
102 | addEndHandler("member",this,&MainHandler::endMember);␊ |
103 | addStartHandler("name",this,&MainHandler::startName);␊ |
104 | addEndHandler("name",this,&MainHandler::endName);␊ |
105 | m_curCompound = 0;␊ |
106 | m_insideMember = FALSE;␊ |
107 | }␊ |
108 | ␊ |
109 | MainHandler::~MainHandler()␊ |
110 | {␊ |
111 | debug(2,"MainHandler::~MainHandler()\n");␊ |
112 | }␊ |
113 | ␊ |
114 | void MainHandler::startCompound(const QXmlAttributes& attrib)␊ |
115 | {␊ |
116 | m_curCompound = new CompoundEntry(257);␊ |
117 | m_curCompound->id = attrib.value("refid");␊ |
118 | m_compounds.append(m_curCompound);␊ |
119 | m_compoundDict.insert(m_curCompound->id,m_curCompound);␊ |
120 | }␊ |
121 | ␊ |
122 | void MainHandler::startName(const QXmlAttributes& /*attrib*/)␊ |
123 | {␊ |
124 | m_curString = "";␊ |
125 | }␊ |
126 | ␊ |
127 | void MainHandler::endName()␊ |
128 | {␊ |
129 | if (m_insideMember)␊ |
130 | {␊ |
131 | m_curMember->name = m_curString;␊ |
132 | }␊ |
133 | else␊ |
134 | {␊ |
135 | m_curCompound->name = m_curString;␊ |
136 | m_compoundNameDict.insert(m_curString,m_curCompound);␊ |
137 | }␊ |
138 | }␊ |
139 | ␊ |
140 | void MainHandler::startMember(const QXmlAttributes& attrib)␊ |
141 | {␊ |
142 | m_insideMember = TRUE;␊ |
143 | m_curMember = new MemberEntry;␊ |
144 | m_curMember->id = attrib.value("refid");␊ |
145 | m_curMember->compound = m_curCompound;␊ |
146 | m_memberDict.insert(m_curMember->id,m_curMember);␊ |
147 | }␊ |
148 | ␊ |
149 | void MainHandler::endMember()␊ |
150 | {␊ |
151 | m_curCompound->memberDict.insert(m_curMember->name,m_curMember);␊ |
152 | QList<CompoundEntry> *cel=0;␊ |
153 | if ((cel=m_memberNameDict.find(m_curMember->name))==0)␊ |
154 | {␊ |
155 | cel = new QList<CompoundEntry>;␊ |
156 | m_memberNameDict.insert(m_curMember->name,cel);␊ |
157 | }␊ |
158 | cel->append(m_curCompound);␊ |
159 | m_insideMember = FALSE;␊ |
160 | }␊ |
161 | ␊ |
162 | void MainHandler::setDebugLevel(int level)␊ |
163 | {␊ |
164 | ::setDebugLevel(level);␊ |
165 | }␊ |
166 | ␊ |
167 | void MainHandler::dump()␊ |
168 | {␊ |
169 | QListIterator<CompoundEntry> cli(m_compounds);␊ |
170 | CompoundEntry *ce;␊ |
171 | for (cli.toFirst();(ce=cli.current());++cli)␊ |
172 | {␊ |
173 | debug(2,"compound id=`%s' name=`%s'\n",ce->id.data(),ce->name.data());␊ |
174 | QDictIterator<MemberEntry> mdi(ce->memberDict);␊ |
175 | MemberEntry *me;␊ |
176 | for (mdi.toFirst();(me=mdi.current());++mdi)␊ |
177 | {␊ |
178 | debug(2," member id=`%s' name=`%s'\n",me->id.data(),me->name.data());␊ |
179 | }␊ |
180 | }␊ |
181 | }␊ |
182 | ␊ |
183 | bool MainHandler::readXMLDir(const char * xmlDirName)␊ |
184 | {␊ |
185 | m_xmlDirName = xmlDirName;␊ |
186 | QString xmlFileName=m_xmlDirName+"/index.xml";␊ |
187 | QFile xmlFile(xmlFileName);␊ |
188 | //printf("Trying %s xmlFile.exists()=%d isReadable()=%d\n",␊ |
189 | // xmlFileName.data(),xmlFile.exists(),xmlFile.isReadable());␊ |
190 | if (xmlFile.exists())␊ |
191 | {␊ |
192 | ErrorHandler errorHandler;␊ |
193 | QXmlInputSource source( xmlFile );␊ |
194 | QXmlSimpleReader reader;␊ |
195 | reader.setContentHandler( this );␊ |
196 | reader.setErrorHandler( &errorHandler );␊ |
197 | reader.parse( source );␊ |
198 | dump();␊ |
199 | return TRUE;␊ |
200 | }␊ |
201 | return FALSE;␊ |
202 | }␊ |
203 | ␊ |
204 | ICompoundIterator *MainHandler::compounds() const␊ |
205 | {␊ |
206 | return new CompoundEntryIterator(this,m_compounds);␊ |
207 | }␊ |
208 | ␊ |
209 | ICompound *MainHandler::compoundById(const char *id) const␊ |
210 | {␊ |
211 | QString ids = id;␊ |
212 | if (ids.isEmpty()) return 0;␊ |
213 | CompoundHandler *ch = m_compoundsLoaded[ids];␊ |
214 | if (ch) // compound already in memory␊ |
215 | {␊ |
216 | ch->addref(); // returning alias -> increase reference counter␊ |
217 | return ch->toICompound(); ␊ |
218 | }␊ |
219 | CompoundEntry *ce = m_compoundDict.find(ids);␊ |
220 | if (ce==0) return 0; // id not found␊ |
221 | // create and load a new compound␊ |
222 | ch = new CompoundHandler(m_xmlDirName);␊ |
223 | if (!ch->parseXML(id))␊ |
224 | {␊ |
225 | // compound could not be initialized.␊ |
226 | delete ch;␊ |
227 | return 0;␊ |
228 | }␊ |
229 | ␊ |
230 | // we disregard the constness here, because the object stays conceptually␊ |
231 | // unchanged.␊ |
232 | MainHandler *that = (MainHandler *)this;␊ |
233 | ch->initialize(that);␊ |
234 | //printf("loading compound %s in memory\n",id);␊ |
235 | that->m_compoundsLoaded.insert(id,ch);␊ |
236 | return ch->toICompound();␊ |
237 | }␊ |
238 | ␊ |
239 | void MainHandler::unloadCompound(CompoundHandler *ch)␊ |
240 | {␊ |
241 | //printf("unloading compound %s from memory\n",ch->id()->latin1());␊ |
242 | bool result = m_compoundsLoaded.remove(ch->id()->latin1()); ␊ |
243 | if (!result) debug(1,"Failed to unload component!\n");␊ |
244 | }␊ |
245 | ␊ |
246 | ICompound *MainHandler::compoundByName(const char *name) const␊ |
247 | {␊ |
248 | QString nameStr = name;␊ |
249 | if (nameStr.isEmpty()) return 0;␊ |
250 | CompoundEntry *ce = m_compoundNameDict[name];␊ |
251 | if (ce==0) return 0; // name not found␊ |
252 | return compoundById(ce->id);␊ |
253 | }␊ |
254 | ␊ |
255 | ICompound *MainHandler::memberById(const char *id) const␊ |
256 | {␊ |
257 | QString ids = id;␊ |
258 | if (ids.isEmpty()) return 0;␊ |
259 | MemberEntry *me = m_memberDict[id];␊ |
260 | if (me==0) return 0; // id not found␊ |
261 | return compoundById(me->compound->id);␊ |
262 | }␊ |
263 | ␊ |
264 | ICompoundIterator *MainHandler::memberByName(const char *name) const␊ |
265 | {␊ |
266 | QString nameStr = name;␊ |
267 | if (nameStr.isEmpty()) return 0;␊ |
268 | QList<CompoundEntry> *cel = m_memberNameDict[name];␊ |
269 | if (cel==0) return 0; // name not found␊ |
270 | return new CompoundEntryIterator(this,*cel);␊ |
271 | }␊ |
272 | ␊ |
273 | IDoxygen *createObjectModel()␊ |
274 | {␊ |
275 | compoundhandler_init();␊ |
276 | sectionhandler_init();␊ |
277 | memberhandler_init();␊ |
278 | dochandler_init();␊ |
279 | graphhandler_init();␊ |
280 | return new MainHandler;␊ |
281 | }␊ |
282 | ␊ |
283 | void MainHandler::release()␊ |
284 | {␊ |
285 | //printf("MainHandler::release()\n");␊ |
286 | QDictIterator<CompoundHandler> chi(m_compoundsLoaded);␊ |
287 | CompoundHandler *ch;␊ |
288 | for (chi.toFirst();(ch=chi.current());++chi)␊ |
289 | {␊ |
290 | debug(1,"Compound %s not released\n",ch->name()->latin1());␊ |
291 | }␊ |
292 | graphhandler_exit();␊ |
293 | dochandler_exit();␊ |
294 | memberhandler_exit();␊ |
295 | sectionhandler_exit();␊ |
296 | compoundhandler_exit();␊ |
297 | delete this;␊ |
298 | }␊ |
299 | ␊ |
300 |