18 #include <qfileinfo.h>
27 #include <qtextcodec.h>
30 #include <qtextstream.h>
105 #define RECURSE_ENTRYTREE(func,var) \
106 do { if (var->children()) { \
107 EntryNavListIterator eli(*var->children()); \
108 for (;eli.current();++eli) func(eli.current()); \
112 #if !defined(_WIN32) || defined(__CYGWIN__)
191 Doxygen::classSDict->
clear();
192 Doxygen::namespaceSDict->
clear();
193 Doxygen::pageSDict->
clear();
194 Doxygen::exampleSDict->
clear();
195 Doxygen::inputNameList->clear();
196 Doxygen::formulaList->clear();
197 Doxygen::sectionDict->
clear();
198 Doxygen::inputNameDict->clear();
199 Doxygen::includeNameDict->clear();
200 Doxygen::exampleNameDict->clear();
201 Doxygen::imageNameDict->clear();
202 Doxygen::dotFileNameDict->clear();
203 Doxygen::mscFileNameDict->clear();
204 Doxygen::diaFileNameDict->clear();
205 Doxygen::formulaDict->clear();
206 Doxygen::formulaNameDict->clear();
225 stats.getLast()->elapsed=((double)
time.elapsed())/1000.0;
235 msg(
"----------------------\n");
236 QListIterator<stat> sli(
stats);
238 for ( sli.toFirst(); (s=sli.current()); ++sli )
259 fprintf(stderr,
"--- inputNameDict stats ----\n");
260 Doxygen::inputNameDict->statistics();
261 fprintf(stderr,
"--- includeNameDict stats ----\n");
262 Doxygen::includeNameDict->statistics();
263 fprintf(stderr,
"--- exampleNameDict stats ----\n");
264 Doxygen::exampleNameDict->statistics();
265 fprintf(stderr,
"--- imageNameDict stats ----\n");
266 Doxygen::imageNameDict->statistics();
267 fprintf(stderr,
"--- dotFileNameDict stats ----\n");
268 Doxygen::dotFileNameDict->statistics();
269 fprintf(stderr,
"--- mscFileNameDict stats ----\n");
270 Doxygen::mscFileNameDict->statistics();
271 fprintf(stderr,
"--- diaFileNameDict stats ----\n");
272 Doxygen::diaFileNameDict->statistics();
275 fprintf(stderr,
"--- aliasDict stats ----\n");
277 fprintf(stderr,
"--- typedefDict stats ----\n");
278 fprintf(stderr,
"--- namespaceAliasDict stats ----\n");
280 fprintf(stderr,
"--- formulaDict stats ----\n");
281 Doxygen::formulaDict->statistics();
282 fprintf(stderr,
"--- formulaNameDict stats ----\n");
283 Doxygen::formulaNameDict->statistics();
284 fprintf(stderr,
"--- tagDestinationDict stats ----\n");
286 fprintf(stderr,
"--- g_compoundKeywordDict stats ----\n");
288 fprintf(stderr,
"--- expandAsDefinedDict stats ----\n");
290 fprintf(stderr,
"--- memGrpInfoDict stats ----\n");
316 QDict<int> *templateNames,
339 {
"allocator", 0, 0,
"T",
"elements", 0, 0, FALSE, FALSE },
340 {
"array", 0, 0,
"T",
"elements", 0, 0, FALSE, FALSE },
341 {
"auto_ptr", 0, 0,
"T",
"ptr", 0, 0, FALSE, FALSE },
342 {
"smart_ptr", 0, 0,
"T",
"ptr", 0, 0, FALSE, FALSE },
343 {
"unique_ptr", 0, 0,
"T",
"ptr", 0, 0, FALSE, FALSE },
344 {
"weak_ptr", 0, 0,
"T",
"ptr", 0, 0, FALSE, FALSE },
345 {
"ios_base", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
346 {
"error_code", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
347 {
"error_category", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
348 {
"system_error", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
349 {
"error_condition", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
350 {
"thread", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
351 {
"basic_ios",
"ios_base", 0,
"Char", 0, 0, 0, FALSE, FALSE },
352 {
"basic_istream",
"basic_ios<Char>", 0,
"Char", 0, 0, 0, TRUE, FALSE },
353 {
"basic_ostream",
"basic_ios<Char>", 0,
"Char", 0, 0, 0, TRUE, FALSE },
354 {
"basic_iostream",
"basic_istream<Char>",
"basic_ostream<Char>",
"Char", 0, 0, 0, FALSE, FALSE },
355 {
"basic_ifstream",
"basic_istream<Char>", 0,
"Char", 0, 0, 0, FALSE, FALSE },
356 {
"basic_ofstream",
"basic_ostream<Char>", 0,
"Char", 0, 0, 0, FALSE, FALSE },
357 {
"basic_fstream",
"basic_iostream<Char>", 0,
"Char", 0, 0, 0, FALSE, FALSE },
358 {
"basic_istringstream",
"basic_istream<Char>", 0,
"Char", 0, 0, 0, FALSE, FALSE },
359 {
"basic_ostringstream",
"basic_ostream<Char>", 0,
"Char", 0, 0, 0, FALSE, FALSE },
360 {
"basic_stringstream",
"basic_iostream<Char>", 0,
"Char", 0, 0, 0, FALSE, FALSE },
361 {
"ios",
"basic_ios<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
362 {
"wios",
"basic_ios<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
363 {
"istream",
"basic_istream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
364 {
"wistream",
"basic_istream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
365 {
"ostream",
"basic_ostream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
366 {
"wostream",
"basic_ostream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
367 {
"ifstream",
"basic_ifstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
368 {
"wifstream",
"basic_ifstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
369 {
"ofstream",
"basic_ofstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
370 {
"wofstream",
"basic_ofstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
371 {
"fstream",
"basic_fstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
372 {
"wfstream",
"basic_fstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
373 {
"istringstream",
"basic_istringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
374 {
"wistringstream",
"basic_istringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
375 {
"ostringstream",
"basic_ostringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
376 {
"wostringstream",
"basic_ostringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
377 {
"stringstream",
"basic_stringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
378 {
"wstringstream",
"basic_stringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
379 {
"basic_string", 0, 0,
"Char", 0, 0, 0, FALSE, TRUE },
380 {
"string",
"basic_string<char>", 0, 0, 0, 0, 0, FALSE, TRUE },
381 {
"wstring",
"basic_string<wchar_t>", 0, 0, 0, 0, 0, FALSE, TRUE },
382 {
"complex", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
383 {
"bitset", 0, 0,
"Bits", 0, 0, 0, FALSE, FALSE },
384 {
"deque", 0, 0,
"T",
"elements", 0, 0, FALSE, TRUE },
385 {
"list", 0, 0,
"T",
"elements", 0, 0, FALSE, TRUE },
386 {
"forward_list", 0, 0,
"T",
"elements", 0, 0, FALSE, TRUE },
387 {
"map", 0, 0,
"K",
"keys",
"T",
"elements", FALSE, TRUE },
388 {
"unordered_map", 0, 0,
"K",
"keys",
"T",
"elements", FALSE, TRUE },
389 {
"multimap", 0, 0,
"K",
"keys",
"T",
"elements", FALSE, TRUE },
390 {
"unordered_multimap", 0, 0,
"K",
"keys",
"T",
"elements", FALSE, TRUE },
391 {
"set", 0, 0,
"K",
"keys", 0, 0, FALSE, TRUE },
392 {
"unordered_set", 0, 0,
"K",
"keys", 0, 0, FALSE, TRUE },
393 {
"multiset", 0, 0,
"K",
"keys", 0, 0, FALSE, TRUE },
394 {
"unordered_multiset", 0, 0,
"K",
"keys", 0, 0, FALSE, TRUE },
395 {
"vector", 0, 0,
"T",
"elements", 0, 0, FALSE, TRUE },
396 {
"queue", 0, 0,
"T",
"elements", 0, 0, FALSE, FALSE },
397 {
"priority_queue", 0, 0,
"T",
"elements", 0, 0, FALSE, FALSE },
398 {
"stack", 0, 0,
"T",
"elements", 0, 0, FALSE, FALSE },
399 {
"valarray", 0, 0,
"T",
"elements", 0, 0, FALSE, FALSE },
400 {
"exception", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
401 {
"bad_alloc",
"exception", 0, 0, 0, 0, 0, FALSE, FALSE },
402 {
"bad_cast",
"exception", 0, 0, 0, 0, 0, FALSE, FALSE },
403 {
"bad_typeid",
"exception", 0, 0, 0, 0, 0, FALSE, FALSE },
404 {
"logic_error",
"exception", 0, 0, 0, 0, 0, FALSE, FALSE },
405 {
"ios_base::failure",
"exception", 0, 0, 0, 0, 0, FALSE, FALSE },
406 {
"runtime_error",
"exception", 0, 0, 0, 0, 0, FALSE, FALSE },
407 {
"bad_exception",
"exception", 0, 0, 0, 0, 0, FALSE, FALSE },
408 {
"domain_error",
"logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
409 {
"invalid_argument",
"logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
410 {
"length_error",
"logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
411 {
"out_of_range",
"logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
412 {
"range_error",
"runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE },
413 {
"overflow_error",
"runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE },
414 {
"underflow_error",
"runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE },
415 { 0, 0, 0, 0, 0, 0, 0, FALSE, FALSE }
421 memEntry->
name = name;
422 memEntry->
type = type;
425 memEntry->
brief =
"STL member";
438 iteratorClassEntry->
fileName =
"[STL]";
440 iteratorClassEntry->
name = name;
442 iteratorClassEntry->
brief =
"STL iterator class";
443 iteratorClassEntry->
hidden = FALSE;
445 EntryNav *iteratorClassEntryNav =
new EntryNav(classEntryNav,iteratorClassEntry);
446 iteratorClassEntryNav->
setEntry(iteratorClassEntry);
447 classEntryNav->
addChild(iteratorClassEntryNav);
457 namespaceEntry->
name =
"std";
459 namespaceEntry->
brief =
"STL namespace";
460 namespaceEntry->
hidden = FALSE;
464 namespaceEntryNav->
setEntry(namespaceEntry);
465 rootNav->
addChild(namespaceEntryNav);
472 fullName.prepend(
"std::");
478 classEntry->
name = fullName;
481 classEntry->
brief =
"STL class";
482 classEntry->
hidden = FALSE;
486 classEntryNav->
setEntry(classEntry);
487 namespaceEntryNav->
addChild(classEntryNav);
504 classEntry->
tArgLists =
new QList<ArgumentList>;
505 classEntry->
tArgLists->setAutoDelete(TRUE);
517 if (fullName==
"std::auto_ptr" || fullName==
"std::smart_ptr" ||
518 fullName==
"std::unique_ptr" || fullName==
"std::weak_ptr")
521 memEntry->
name =
"operator->";
522 memEntry->
args =
"()";
523 memEntry->
type =
"T*";
526 memEntry->
brief =
"STL member";
531 classEntryNav->
addChild(memEntryNav);
547 addSTLIterator(classEntryNav,fullName+
"::const_reverse_iterator");
568 scope+=
"::"+pd->
name();
581 QListIterator<Grouping> gli(*root->
groups);
583 for (;(g=gli.current());++gli)
589 if (root->
brief.isEmpty())
615 ((!includeExternal && rootNav->
tagInfo()==0) ||
616 ( includeExternal && rootNav->
tagInfo()!=0))
638 "group %s: ignoring title \"%s\" that does not match old title \"%s\"\n",
676 for (;(e=eli.current());++eli)
704 if ((gd=Doxygen::groupSDict->find(rootNav->
name())))
712 scope+=
"::"+gd->
name();
734 if ((gd=Doxygen::groupSDict->find(root->
name)))
747 for (;(e=eli.current());++eli)
787 "file %s already documented. "
788 "Skipping documentation.",
803 QListIterator<Grouping> gli(*root->
groups);
805 for (;(g=gli.current());++gli)
819 const char *fn = root->
fileName.data();
821 text.sprintf(
"the name `%s' supplied as "
822 "the second argument in the \\file statement ",
826 text+=
"matches the following input files:\n";
828 text+=
"Please use a more specific name by "
829 "including a (larger) part of the path!";
833 text+=
"is not an input file";
846 (!root->
doc.stripWhiteSpace().isEmpty() ||
847 !root->
brief.stripWhiteSpace().isEmpty() ||
856 if (!includeFile.isEmpty() && includeFile.at(0)==
'"')
859 includeFile=includeFile.mid(1,includeFile.length()-2);
861 else if (!includeFile.isEmpty() && includeFile.at(0)==
'<')
864 includeFile=includeFile.mid(1,includeFile.length()-2);
871 if (!includeFile.isEmpty() &&
872 (fd=
findFileDef(Doxygen::inputNameDict,includeFile,ambig))==0
876 text.sprintf(
"the name `%s' supplied as "
877 "the argument of the \\class, \\struct, \\union, or \\include command ",
882 text+=
"matches the following input files:\n";
884 text+=
"Please use a more specific name by "
885 "including a (larger) part of the path!";
889 text+=
"is not an input file";
893 else if (includeFile.isEmpty() && ifd &&
905 if (!iName.isEmpty())
907 if (iName.at(0)==
'<') local=FALSE;
908 else if (iName.at(0)==
'"') local=TRUE;
909 if (iName.at(0)==
'"' || iName.at(0)==
'<')
911 iName=iName.mid(1,iName.length()-2);
952 if (!nsName.isEmpty() && nsName.at(0)!=
'@' &&
972 if (root==0)
return 0;
977 result = findScope(root->
parent,level+1);
1012 if (idx==-1)
return prevScope;
1013 QCString nsName = name.mid(idx,l);
1014 if (nsName.isEmpty())
return prevScope;
1015 if (!fullScope.isEmpty()) fullScope+=
"::";
1020 if (nd==0) cd =
getClass(fullScope);
1025 else if (nd==0 && cd==0 && fullScope.find(
'<')==-1)
1030 "[generated]",1,1,fullScope,
1031 tagInfo?tagInfo->
tagName:QCString(),
1032 tagInfo?tagInfo->
fileName:QCString());
1036 Doxygen::namespaceSDict->
inSort(fullScope,nd);
1054 prevScope=innerScope;
1074 int p=i1+l1,l2=0,i2;
1077 QCString nestedNameSpecifier = scope.mid(i1,l1);
1085 if (orgScope==Doxygen::globalScope && fileScope &&
1091 for (ni.toFirst();((nd=ni.current()) && resultScope==0);++ni)
1117 for (ui.toFirst();(usedFd=ui.current());++ui)
1124 QCString fqn = QCString(ui.currentKey())+
1125 scope.right(scope.length()-p);
1150 const QCString &name,
1151 const QList<ArgumentList> *tArgLists)
1153 if (tArgLists==0)
return 0;
1155 QListIterator<ArgumentList> ali(*tArgLists);
1159 while ((i=name.find(
"::",p))!=-1)
1175 return ali.current();
1251 QCString fullName = root->
name;
1257 QCString qualifiedName = fullName;
1260 qualifiedName.prepend(scName+
"::");
1267 cd ? qPrint(cd->
name()) : qPrint(root->
name), qPrint(qualifiedName),cd);
1271 fullName=cd->
name();
1306 QCString namespaceName;
1313 QCString refFileName;
1320 if (fullName.find(
"::")!=-1)
1334 fullName=fullName.left(i);
1371 Doxygen::classSDict->
append(fullName,cd);
1376 Doxygen::genericsDict->
insert(fullName,cd);
1431 for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
1440 for (cli.toFirst();(cd=cli.current());++cli)
1467 for (cli.toFirst();(cd=cli.current());++cli)
1484 "Internal inconsistency: scope for class %s not "
1485 "found!",name.data()
1499 for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
1502 for (cli.toFirst();(cd=cli.current());++cli)
1512 for (ncli.toFirst();(ncd=ncli.current());++ncli)
1514 if (ncd->partOfGroups()==0)
1518 ncd->makePartOfGroup(gd);
1532 if (fullName.right(2)==
"::") fullName=fullName.left(fullName.length()-2);
1533 fullName+=
"."+fieldName;
1562 for (gli.toFirst();(gd=gli.current());++gli)
1569 Doxygen::classSDict->
append(fullName,cd);
1576 for (li.toFirst();(md=li.current());++li)
1612 const QCString &prefix,
int count)
1623 for (li.toFirst();(md=li.current());++li)
1626 if (type.find(
"::@")!=-1)
1630 for (it.toFirst();(icd=it.current());++it)
1634 if (type.find(icd->name())!=-1)
1636 QCString name = md->
name();
1637 if (name.at(0)==
'@') name =
"__unnamed__";
1638 if (!prefix.isEmpty()) name.prepend(prefix+
".");
1658 for (pli.toFirst();(pmd=pli.current());++pli)
1681 for (it.toFirst();(icd=it.current());++it)
1683 if (icd->name().find(
"@")==-1)
1697 for (cli.toFirst();(cd=cli.current());++cli)
1718 !rootNav->
name().isEmpty()
1726 QCString fName = root->
name;
1733 if (!fullName.isEmpty())
1738 if ((nd=Doxygen::namespaceSDict->find(fullName)))
1766 QCString tagFileName;
1800 Doxygen::namespaceSDict->
inSort(fullName,nd);
1830 const QCString &name)
1838 for (unli.toFirst();(und=unli.current());++unli)
1840 QCString uScope=und->
name()+
"::";
1858 if (name.right(2)==
"::")
1860 name=name.left(name.length()-2);
1862 if (!name.isEmpty())
1876 if (!nsName.isEmpty())
1886 int scopeOffset = nsName.length();
1889 QCString scope=scopeOffset>0 ?
1890 nsName.left(scopeOffset)+
"::" : QCString();
1897 else if ((scopeOffset=nsName.findRev(
"::",scopeOffset-1))==-1)
1901 }
while (scopeOffset>=0 && usingNd==0);
1903 if (usingNd==0 && nd)
1907 while (pnd && usingNd==0)
1924 if (usingNd==0 && fd)
1944 fd->addUsingDirective(usingNd);
1960 QListIterator<Grouping> gli(*root->
groups);
1962 for (;(g=gli.current());++gli)
1972 fd->insertNamespace(nd);
1973 fd->addUsingDirective(nd);
1980 Doxygen::namespaceSDict->
inSort(name,nd);
2030 if (!root->
name.isEmpty())
2042 if (!scName.isEmpty())
2058 usingCd = Doxygen::hiddenClasses->
find(name);
2070 Doxygen::hiddenClasses->
append(root->
name,usingCd);
2071 usingCd->setArtificial(TRUE);
2072 usingCd->setLanguage(root->
lang);
2077 qPrint(usingCd->
name()),
2078 nd?qPrint(nd->
name()):
2079 fd?qPrint(fd->
name()):
2118 int i=rootNav->
name().find(
"::");
2121 QCString scope=rootNav->
name().left(i);
2122 QCString memName=rootNav->
name().right(rootNav->
name().length()-i-2);
2135 for ( ; (mi=mnii.current()) ; ++mnii )
2147 QCString fileName = root->
fileName;
2148 if (fileName.isEmpty() && rootNav->
tagInfo())
2164 if (!root->
doc.isEmpty() || !root->
brief.isEmpty())
2210 for (fnli.toFirst();(fn=fnli.current());++fnli)
2214 for (;(fd=fni.current());++fni)
2221 for (fnli.toFirst();(fn=fnli.current());++fnli)
2225 for (fni.toFirst();(fd=fni.current());++fni)
2242 const QCString &name,
2251 QCString scopeSeparator=
"::";
2259 " class variable:\n"
2260 " `%s' `%s'::`%s' `%s' prot=`%d ann=%d init=`%s'\n",
2271 if (!root->
type.isEmpty())
2277 def=
"using "+name+
" = "+root->
type.mid(7);
2281 def=root->
type+
" "+name+root->
args;
2288 def=
"using "+qualScope+scopeSeparator+name+
" = "+root->
type.mid(7);
2292 def=root->
type+
" "+qualScope+scopeSeparator+name+root->
args;
2300 def=name+root->
args;
2304 def=qualScope+scopeSeparator+name+root->
args;
2307 def.stripPrefix(
"static ");
2317 for (mni.toFirst();(md=mni.current());++mni)
2341 QCString fileName = root->
fileName;
2342 if (fileName.isEmpty() && rootNav->
tagInfo())
2400 Doxygen::memberNameSDict->
append(name,mn);
2418 const QCString &scope,
2419 const QCString &name,
2426 " global variable:\n"
2427 " type=`%s' scope=`%s' name=`%s' args=`%s' prot=`%d mtype=%d lang=%d\n",
2442 QCString type = root->
type;
2443 type.stripPrefix(
"typedef ");
2444 if (type.left(7)==
"struct " || type.left(6)==
"union ")
2446 type.stripPrefix(
"struct ");
2447 type.stripPrefix(
"union ");
2448 static QRegExp re(
"[a-z_A-Z][a-z_A-Z0-9]*");
2450 s = re.match(type,0,&l);
2453 QCString typeValue = type.mid(s,l);
2470 if (!scope.isEmpty())
2472 if (scope.find(
'@')!=-1)
return 0;
2482 if (nd && !nd->
name().isEmpty() && nd->
name().at(0)!=
'@' &&
2490 if (!root->
type.isEmpty())
2494 def=
"using "+nd->
name()+sep+name+
" = "+root->
type;
2503 def=nd->
name()+sep+name+root->
args;
2508 if (!root->
type.isEmpty() && !root->
name.isEmpty())
2510 if (name.at(0)==
'@')
2518 def=
"using "+root->
name+
" = "+root->
type.mid(7);
2522 def=root->
type+
" "+name+root->
args;
2528 def=name+root->
args;
2531 def.stripPrefix(
"static ");
2539 if (!scope.isEmpty())
2545 for (mni.toFirst();(md=mni.current());++mni)
2560 root->
args.find(
'[')!=-1;
2561 bool staticsInDifferentFiles =
2567 !staticsInDifferentFiles
2582 QCString fileName = root->
fileName;
2583 if (fileName.isEmpty() && rootNav->
tagInfo())
2589 " new variable, nd=%s!\n",nd?qPrint(nd->
name()):
"<global>");
2622 if (nd && !nd->
name().isEmpty() && nd->
name().at(0)!=
'@')
2645 Doxygen::functionNameSDict->
append(name,mn);
2661 static const QRegExp re(
"([^)]*[\\*\\^][^)]*)");
2663 int bb=type.find(
'<');
2664 int be=type.findRev(
'>');
2665 if (!type.isEmpty() &&
2666 (i=re.match(type,0,&l))!=-1 &&
2667 type.find(
"operator")==-1 &&
2668 (type.find(
")(")==-1 || type.find(
"typedef ")!=-1) &&
2673 if (pLength) *pLength=l;
2690 static QRegExp initChars(
"[0-9\"'&*!^]+");
2691 static QRegExp idChars(
"[a-z_A-Z][a-z_A-Z0-9]*");
2708 else if ((fd = rootNav->
fileDef()) &&
2709 (fd->
name().right(2)==
".c" || fd->
name().right(2)==
".h")
2715 if (root->
type.isEmpty())
2731 if (!typeIsClass && (ti=type.find(
'<'))!=-1)
2741 if (al==0 || al->isEmpty())
2748 for (ali.toFirst();(a=ali.current());++ali)
2750 if (!a->
name.isEmpty() || !a->
defval.isEmpty())
2752 if (a->
name.find(initChars)==0)
2773 if (a->
type.at(a->
type.length()-1)==
'*' ||
2774 a->
type.at(a->
type.length()-1)==
'&')
2780 if (a->
type.find(initChars)==0)
2786 if (resType.isEmpty()) resType=a->
type;
2788 if (idChars.match(resType,0,&len)==0)
2790 resType=resType.left(len);
2792 if (resType==
"int" || resType==
"long" || resType==
"float" ||
2793 resType==
"double" || resType==
"char" || resType==
"signed" ||
2794 resType==
"const" || resType==
"unsigned" || resType==
"void")
2818 " type=`%s' name=`%s' args=`%s' bodyLine=`%d' mGrpId=%d relates=%s\n",
2828 if (root->
type.isEmpty() && root->
name.find(
"operator")==-1 &&
2829 (root->
name.find(
'*')!=-1 || root->
name.find(
'&')!=-1))
2836 static const QRegExp reName(
"[a-z_A-Z][a-z_A-Z0-9]*");
2838 int i=root->
args.isEmpty() ? -1 : reName.match(root->
args,0,&l);
2842 root->
args=root->
args.mid(i+l,root->
args.find(
')',i+l)-i-l);
2854 int ai = root->
type.find(
'[',i);
2857 root->
args.prepend(root->
type.right(root->
type.length()-ai));
2860 else if (root->
type.find(
')',i)!=-1)
2863 root->
args.prepend(
") ");
2867 else if (root->
type.find(
"typedef ")!=-1 && root->
type.right(2)==
"()")
2870 root->
args.prepend(
") ");
2880 QCString scopeName = p->
name();
2881 if (!scopeName.isEmpty())
2883 scope.prepend(scopeName);
2890 QCString type=root->
type.stripWhiteSpace();
2892 bool isRelated=FALSE;
2893 bool isMemberOf=FALSE;
2897 QCString annScopePrefix=scope.left(scope.length()-classScope.length());
2899 if (root->
name.findRev(
"::")!=-1)
2901 if (root->
type==
"friend class" || root->
type==
"friend struct" ||
2902 root->
type==
"friend union")
2929 else if (type.left(8)==
"typedef ")
2931 else if (type.left(7)==
"friend ")
2951 if (cd==0 && classScope!=scope) cd=
getClass(classScope);
2961 int si=scope.find(
'@');
2965 static bool inlineSimpleStructs =
Config_getBool(INLINE_SIMPLE_STRUCTS);
2966 if (si!=-1 && !inlineSimpleStructs)
2970 pScope = scope.left(QMAX(si-2,0));
2971 if (!pScope.isEmpty())
2972 pScope.prepend(annScopePrefix);
2973 else if (annScopePrefix.length()>2)
2974 pScope=annScopePrefix.left(annScopePrefix.length()-2);
2975 if (name.at(0)!=
'@')
2977 if (!pScope.isEmpty() && (pcd=
getClass(pScope)))
3013 else if (!name.isEmpty())
3029 if (!rootNav->
name().isEmpty() &&
3031 rootNav->
type().find(
"typedef ")!=-1
3040 for (;(e=eli.current());++eli)
3058 if (!rootNav->
name().isEmpty() &&
3078 for (;(e=eli.current());++eli)
3096 QCString
const& rname)
3103 QCString fileName = root->
fileName;
3104 if (fileName.isEmpty() && rootNav->
tagInfo())
3126 QCString
const def = root->
type +
" " + rname;
3132 " Interface Member:\n"
3133 " `%s' `%s' proto=%d\n"
3143 if ((mn=Doxygen::memberNameSDict->find(rname)))
3151 Doxygen::memberNameSDict->
append(rname,mn);
3179 "EXPORTED_INTERFACE_SEC:\n"
3180 " `%s' `%s'::`%s' `%s' relates=`%s' relatesType=`%d' file=`%s' line=`%d' bodyLine=`%d' #tArgLists=%d mGrpId=%d spec=%lld proto=%d docFile=%s\n",
3199 if (!rname.isEmpty())
3201 QCString
const scope = rootNav->
parent()->
name();
3215 else if (rname.isEmpty())
3218 "Illegal member name found.");
3224 switch (rootNav->
lang())
3241 const QCString &rname,
bool isFriend)
3247 static QRegExp re(
"([a-z_A-Z0-9: ]*[ &*]+[ ]*");
3248 int ts=root->
type.find(
'<');
3249 int te=root->
type.findRev(
'>');
3250 int i=re.match(root->
type,0,&l);
3251 if (i!=-1 && ts!=-1 && ts<te && ts<i && i<te)
3264 if (name.left(2)==
"::") name=name.right(name.length()-2);
3275 name.left(9)!=
"operator " && (i=name.find(
'<'))!=-1 && name.find(
'>')!=-1)
3280 QCString fileName = root->
fileName;
3281 if (fileName.isEmpty() && rootNav->
tagInfo())
3319 if (scopeSeparator!=
"::")
3321 qualScope =
substitute(qualScope,
"::",scopeSeparator);
3326 scopeSeparator=
"::";
3330 if (!root->
type.isEmpty())
3334 def=root->
type+
" "+name;
3338 def=root->
type+
" "+name+root->
args;
3349 def=name+root->
args;
3355 if (!root->
type.isEmpty())
3359 def=root->
type+
" "+qualScope+scopeSeparator+name;
3363 def=root->
type+
" "+qualScope+scopeSeparator+name+root->
args;
3370 def=qualScope+scopeSeparator+name;
3374 def=qualScope+scopeSeparator+name+root->
args;
3378 if (def.left(7)==
"friend ") def=def.right(def.length()-7);
3385 " `%s' `%s'::`%s' `%s' proto=%d\n"
3398 if ((mn=Doxygen::memberNameSDict->find(name)))
3406 Doxygen::memberNameSDict->
append(name,mn);
3429 " `%s' `%s'::`%s' `%s' relates=`%s' relatesType=`%d' file=`%s' line=`%d' bodyLine=`%d' #tArgLists=%d mGrpId=%d spec=%lld proto=%d docFile=%s\n",
3446 bool isFriend=root->
type.find(
"friend ")!=-1;
3451 if (!rname.isEmpty() && scope.find(
'@')==-1)
3459 int memIndex=rname.findRev(
"::");
3462 if (cd && scope+
"::"==rname.left(scope.length()+2))
3465 rname=rname.right(rname.length()-rootNav->
parent()->
name().length()-2);
3469 bool isMember=FALSE;
3472 int ts=rname.find(
'<');
3473 int te=rname.find(
'>');
3474 if (memIndex>0 && (ts==-1 || te==-1))
3491 isMember=memIndex<ts || memIndex>te;
3495 static QRegExp re(
"([a-z_A-Z0-9: ]*[ &*]+[ ]*");
3496 int ts=root->
type.find(
'<');
3497 int te=root->
type.findRev(
'>');
3503 (root->
type.isEmpty() ||
3504 ((ti=root->
type.find(re,0))==-1 ||
3505 (ts!=-1 && ts<te && ts<ti && ti<te) ||
3506 root->
args.find(
")[")!=-1) ||
3507 root->
type.find(
")(")!=-1 || root->
type.find(
"operator")!=-1 ||
3513 qPrint(rname),qPrint(cd->
name()));
3521 root->
type.left(7)!=
"extern " && root->
type.left(8)!=
"typedef "
3532 if ((mn=Doxygen::functionNameSDict->find(rname)))
3536 for (mni.toFirst();(!found && (md=mni.current()));++mni)
3541 QCString fullScope = scope;
3542 QCString parentScope = rootNav->
parent()->
name();
3543 if (!parentScope.isEmpty() && !
leftScopeMatch(parentScope,scope))
3545 if (!scope.isEmpty()) fullScope.prepend(
"::");
3546 fullScope.prepend(parentScope);
3550 FileDef *mfd = md->getFileDef();
3551 QCString nsName,rnsName;
3552 if (mnd) nsName = mnd->
name().copy();
3553 if (rnd) rnsName = rnd->
name().copy();
3561 bool sameNumTemplateArgs = TRUE;
3562 bool matchingReturnTypes = TRUE;
3565 if (mdTempl->count()!=root->
tArgLists->getLast()->count())
3567 sameNumTemplateArgs = FALSE;
3571 matchingReturnTypes = FALSE;
3575 bool staticsInDifferentFiles =
3576 root->
stat && md->isStatic() && root->
fileName!=md->getDefFileName();
3582 sameNumTemplateArgs &&
3583 matchingReturnTypes &&
3584 !staticsInDifferentFiles
3588 if (root->
groups->getFirst()!=0)
3590 gd = Doxygen::groupSDict->
find(root->
groups->getFirst()->groupname.data());
3595 found=(mnd && rnd && nsName==rnsName) ||
3596 ((mnd==0 && rnd==0 && mfd!=0 &&
3601 if (!found && gd && gd==md->getGroupDef() && nsName==rnsName)
3615 if (md->documentation().isEmpty() && !root->
doc.isEmpty())
3622 md->setDeclArgumentList(argList);
3626 md->setArgumentList(argList);
3632 md->setDocsForDefinition(!root->
proto);
3633 if (md->getStartBodyLine()==-1 && root->
bodyLine!=-1)
3636 md->setBodyDef(rfd);
3639 if (md->briefDescription().isEmpty() && !root->
brief.isEmpty())
3641 md->setArgsString(root->
args);
3645 md->addSectionsToDefinition(root->
anchors);
3647 md->enableCallGraph(md->hasCallGraph() || root->
callGraph);
3648 md->enableCallerGraph(md->hasCallerGraph() || root->
callerGraph);
3651 if (md->getGroupDef()==0 && root->
groups->getFirst()!=0)
3655 else if (md->getGroupDef()!=0 && root->
groups->count()==0)
3658 root->
groups->append(
new Grouping(md->getGroupDef()->name(), md->getGroupPri()));
3660 else if (md->getGroupDef()!=0 && root->
groups->getFirst()!=0)
3667 if (md->isPrototype() && !root->
proto)
3669 md->setPrototype(FALSE);
3715 if (!nscope.isEmpty())
3721 if (!scope.isEmpty())
3732 if (!root->
type.isEmpty())
3736 def=root->
type+
" "+scope+name;
3740 def=root->
type+
" "+scope+name+root->
args;
3747 def=scope+name.copy();
3751 def=scope+name+root->
args;
3755 " Global Function:\n"
3756 " `%s' `%s'::`%s' `%s' proto=%d\n"
3774 if (nd && !nd->
name().isEmpty() && nd->
name().at(0)!=
'@')
3791 if ((mn=Doxygen::functionNameSDict->find(name)))
3799 Doxygen::functionNameSDict->
append(name,mn);
3829 else if (rname.isEmpty())
3832 "Illegal member name found."
3848 for (;(fn=fnli.current());++fnli)
3852 if ((mn=Doxygen::memberNameSDict->find(fn->
memberName())))
3857 for (;(fmd=fni.current());++fni)
3861 for (;(mmd=mni.current());++mni)
3937 for (;(mn=mnli.current());++mnli)
3943 for (;(mdec=mni1.current());++mni1)
3945 if (mdec->isPrototype() ||
3946 (mdec->isVariable() && mdec->isExternal())
3950 for (;(mdef=mni2.current());++mni2)
3965 for (;(mn=mnli.current());++mnli)
3970 for (;(md=mni.current());++mni)
3988 mdec->getOuterScope(),mdec->getFileDef(),mdecAl,
3994 MemberSDict *decDict = mdec->getReferencesMembers();
3999 for (msdi.toFirst();(rmd=msdi.current());++msdi)
4001 if (decDict==0 || decDict->
find(rmd->
name())==0)
4011 for (msdi.toFirst();(rmd=msdi.current());++msdi)
4013 if (defDict==0 || defDict->
find(rmd->
name())==0)
4021 decDict = mdec->getReferencedByMembers();
4026 for (msdi.toFirst();(rmd=msdi.current());++msdi)
4028 if (decDict==0 || decDict->
find(rmd->
name())==0)
4038 for (msdi.toFirst();(rmd=msdi.current());++msdi)
4040 if (defDict==0 || defDict->
find(rmd->
name())==0)
4059 for (mnli.toFirst();(mn=mnli.current());++mnli)
4064 for (mni.toFirst();(md=mni.current());++mni)
4068 if ((rmn=Doxygen::memberNameSDict->find(md->
name())))
4073 for (rmni.toFirst();(rmd=rmni.current());++rmni)
4108 QDict<int> *templateNames =
new QDict<int>(17);
4109 templateNames->setAutoDelete(TRUE);
4110 static QRegExp re(
"[a-z_A-Z][a-z_A-Z0-9:]*");
4111 if (templateArguments)
4116 for (ali.toFirst();(arg=ali.current());++ali,count++)
4119 while ((i=re.match(name,p,&l))!=-1)
4121 QCString n = name.mid(i,l);
4124 if (templateNames->find(n)==0)
4126 templateNames->insert(n,
new int(count));
4133 return templateNames;
4147 if (context && cd!=context)
4163 result = Doxygen::genericsDict->
find(name);
4182 QDict<int> *templateNames=0
4191 for (;(mni=mnili.current());++mnili)
4195 for (mnii.toFirst();(mi=mnii.current());++mnii)
4203 if (!typedefValue.isEmpty())
4205 type = typedefValue;
4208 QCString usedClassName;
4231 usedClassName = typeCd->
name();
4234 int sp=usedClassName.find(
'<');
4236 int si=usedClassName.findRev(
"::",sp);
4246 bool delTempNames=FALSE;
4247 if (templateNames==0)
4260 for (ali.toFirst();(arg=ali.current());++ali,++count)
4262 if (arg->name==usedName)
4267 ClassDef *usedCd = Doxygen::hiddenClasses->
find(usedName);
4279 Doxygen::hiddenClasses->
append(usedName,usedCd);
4305 delete templateNames;
4309 if (!found && !type.isEmpty())
4314 if (type.right(2)==
"(*" || type.right(2)==
"(^")
4325 Doxygen::hiddenClasses->
append(type,usedCd);
4353 QDict<int> *templateNames=0
4361 QListIterator<BaseInfo> bii(*root->
extends);
4363 for (bii.toFirst();(bi=bii.current());++bii)
4367 bool delTempNames=FALSE;
4368 if (templateNames==0)
4388 bool b =
Config_getBool(HIDE_UNDOC_RELATIONS) ? TRUE : isArtificial;
4401 delete templateNames;
4411 ClassDef *templateClass,
const QCString &templSpec,
4412 QDict<int> *templateNames,
4416 qPrint(templateClass->
name()),qPrint(templSpec));
4430 bool existingClass = (templSpec ==
4433 if (existingClass)
return TRUE;
4435 bool freshInstance=FALSE;
4444 Doxygen::classSDict->
append(instanceClass->
name(),instanceClass);
4450 if (templateRootNav)
4452 bool unloadNeeded=FALSE;
4453 Entry *templateRoot = templateRootNav->
entry();
4454 if (templateRoot==0)
4457 templateRoot = templateRootNav->
entry();
4458 ASSERT(templateRoot!=0);
4463 qPrint(templateRoot->
name),qPrint(templSpec));
4470 isArtificial,templArgs,templateNames);
4497 int index=n.find(
'<');
4525 int len = s.length();
4526 bool insideString=FALSE;
4527 bool insideChar=FALSE;
4529 while (e<len && brCount!=0)
4535 if (!insideString && !insideChar)
4537 if (e<len-1 && s.at(e+1)==
'<')
4539 else if (roundCount==0)
4544 if (!insideString && !insideChar)
4546 if (e<len-1 && s.at(e+1)==
'>')
4548 else if (roundCount==0)
4553 if (!insideString && !insideChar)
4557 if (!insideString && !insideChar)
4563 if (insideString && pc!=
'\\')
4572 if (insideChar && pc!=
'\\')
4582 return brCount==0 ? e : -1;
4590 QDict<int> *templateNames,
4610 QCString biName=bi->
name;
4611 bool explicitGlobalScope=FALSE;
4613 if (biName.left(2)==
"::")
4615 biName=biName.right(biName.length()-2);
4616 explicitGlobalScope=TRUE;
4620 bool lastParent=FALSE;
4624 QCString scopeName= parentNode ? parentNode->
name().data() :
"";
4625 int scopeOffset=explicitGlobalScope ? 0 : scopeName.length();
4631 QCString baseClassName=biName;
4634 baseClassName.prepend(scopeName.left(scopeOffset)+
"::");
4664 || explicitGlobalScope
4672 Debug::Classes,0,
" class relation %s inherited/used by %s found (%s and %s) templSpec='%s'\n",
4673 qPrint(baseClassName),
4674 qPrint(rootNav->
name()),
4680 int i=baseClassName.find(
'<');
4681 int si=baseClassName.findRev(
"::",i==-1 ? baseClassName.length() : i);
4686 baseClass = Doxygen::genericsDict->
find(baseClassName.left(i));
4689 if (baseClass==0 && i!=-1)
4699 baseClassName=baseClassName.left(i)+baseClassName.right(baseClassName.length()-e);
4700 baseClass=
getResolvedClass(explicitGlobalScope ? Doxygen::globalScope : context,
4712 else if (baseClass && !templSpec.isEmpty())
4723 baseClass = templClass;
4724 templSpec.resize(0);
4731 if (!found && si!=-1)
4733 QCString tmpTemplSpec;
4736 baseClass=
getResolvedClass(explicitGlobalScope ? Doxygen::globalScope : context,
4744 found=baseClass!=0 && baseClass!=cd;
4745 if (found) templSpec = tmpTemplSpec;
4761 found = baseClass!=0 && baseClass!=cd;
4772 found = baseClass!=0 && baseClass!=cd;
4775 bool isATemplateArgument = templateNames!=0 && templateNames->find(biName)!=0;
4801 if (baseClassTypeDef==0)
4811 if (baseClassTypeDef || cd->
isCSharp())
4827 "Detected potential recursive class relation "
4828 "between class %s and base class %s!",
4829 cd->
name().data(),baseClass->
name().data()
4835 else if (mode==
Undocumented && (scopeOffset==0 || isATemplateArgument))
4838 " New undocumented base class `%s' baseClassName=%s templSpec=%s isArtificial=%d\n",
4839 qPrint(biName),qPrint(baseClassName),qPrint(templSpec),isArtificial
4842 if (isATemplateArgument)
4844 baseClass=Doxygen::hiddenClasses->
find(baseClassName);
4850 Doxygen::hiddenClasses->
append(baseClassName,baseClass);
4857 baseClass=Doxygen::classSDict->
find(baseClassName);
4865 Doxygen::classSDict->
append(baseClassName,baseClass);
4868 int si = baseClassName.findRev(
"::");
4872 if (sd==0 || sd==Doxygen::globalScope)
4879 if (biName.right(2)==
"-p")
4881 biName=
"<"+biName.left(biName.length()-2)+
">";
4890 if (baseClassName.right(2)==
"-p")
4906 "Detected potential recursive class relation "
4907 "between class %s and base class %s!\n",
4908 root->
name.data(),baseClassName.data()
4919 else if ((scopeOffset=scopeName.findRev(
"::",scopeOffset-1))==-1)
4924 }
while (scopeOffset>=0);
4932 parentNode=parentNode->
parent();
4934 }
while (lastParent);
4944 if ( !rootNav->
name().isEmpty() )
4956 bool extends = root->
extends->count()>0;
4958 if (extends)
return TRUE;
4983 (i=bName.find(
'<'))!=-1)
4987 bName=bName.left(i);
5000 for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
5003 for (;(rootNav=edi.current());++edi)
5021 for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
5024 for (;(rootNav=edi.current());++edi)
5042 for (cli.toFirst();cli.current();++cli) cli.current()->visited=FALSE;
5045 for (;(rootNav=edi.current());++edi)
5059 bName.right(2)!=
"::")
5061 if (!root->
name.isEmpty() && root->
name.find(
'@')==-1 &&
5069 "Compound %s is not documented.",
5082 for (;(rootNav=edi.current());++edi)
5091 QDict<ClassDef> *templInstances = 0;
5095 QDictIterator<ClassDef> tdi(*templInstances);
5097 for (tdi.toFirst();(tcd=tdi.current());++tdi)
5100 QCString templSpec = tdi.currentKey();
5103 QList<BaseInfo> *baseList=root->
extends;
5104 QListIterator<BaseInfo> it(*baseList);
5106 for (;(bi=it.current());++it)
5117 QDict<int> *actualTemplateNames =
new QDict<int>(17);
5118 actualTemplateNames->setAutoDelete(TRUE);
5119 QDictIterator<int> qdi(*templateNames);
5120 for (qdi.toFirst();qdi.current();++qdi)
5122 int templIndex = *qdi.current();
5124 if (templIndex<(
int)templArgs->count())
5126 actArg=templArgs->at(templIndex);
5129 baseClassNames!=0 &&
5130 baseClassNames->find(actArg->
type)!=0 &&
5131 actualTemplateNames->find(actArg->
type)==0
5134 actualTemplateNames->insert(actArg->
type,
new int(templIndex));
5137 delete templateNames;
5146 delete actualTemplateNames;
5164 for (cli.toFirst();(cd=cli.current());++cli)
5170 for (fnli.toFirst();(fn=fnli.current());++fnli)
5174 for (;(fd=fni.current());++fni)
5181 for (nli.toFirst();(nd=nli.current());++nli)
5187 for (gli.toFirst();(gd=gli.current());++gli)
5199 for (mnli.toFirst();(mn=mnli.current());++mnli)
5203 for (mni.toFirst();(md=mni.current());++mni)
5209 for (fmnli.toFirst();(mn=fmnli.current());++fmnli)
5213 for (mni.toFirst();(md=mni.current());++mni)
5221 for (cli.toFirst();(cd=cli.current());++cli)
5228 for (fnli.toFirst();(fn=fnli.current());++fnli)
5232 for (;(fd=fni.current());++fni)
5240 for (nli.toFirst();(nd=nli.current());++nli)
5247 for (gli.toFirst();(gd=gli.current());++gli)
5254 for (pdi.toFirst();(pd=pdi.current());++pdi)
5266 name,pd->
title(),0,0);
5272 for (ddi.toFirst();(dd=ddi.current());++ddi)
5293 for (di.toFirst();(rl=di.current());++di)
5314 QCString fDecl=funcDecl;
5316 fDecl.stripPrefix(
"extern ");
5324 fullName = cd->
name();
5326 fullName = nd->
name();
5328 if (!fullName.isEmpty()) fullName+=
"::";
5329 fullName+=md->
name();
5357 if (!root->
doc.isEmpty())
5426 "member %s belongs to two different groups. The second "
5427 "one found here will be ignored.",
5445 const char *scopeName)
5458 const QCString &namespaceName,
5461 const char *tempArg,
5467 "2. findGlobalMember(namespace=%s,type=%s,name=%s,tempArg=%s,decl=%s)\n",
5468 qPrint(namespaceName),qPrint(type),qPrint(name),qPrint(tempArg),qPrint(decl));
5470 if (n.isEmpty())
return FALSE;
5471 if (n.find(
"::")!=-1)
return FALSE;
5475 mn=Doxygen::functionNameSDict->
find(n);
5484 for (mni.toFirst();(md=mni.current()) && !found;++mni)
5501 if ((namespaceName.isEmpty() && nd==0) ||
5502 (nd && nd->
name()==namespaceName) ||
5507 qPrint(md->
name()),qPrint(namespaceName));
5510 if (!namespaceName.isEmpty()) rnd = Doxygen::namespaceSDict->find(namespaceName);
5514 (mdAl==0 && root->
argList->count()==0) ||
5528 if (root->
tArgLists->getLast()->count()!=mdTempl->count())
5573 QCString fullFuncDecl=decl;
5576 QCString(
"no matching file member found for \n")+
substitute(fullFuncDecl,
"%",
"%%");
5579 warnMsg+=
"\nPossible candidates:\n";
5580 for (mni.toFirst();(md=mni.current());++mni)
5584 warnMsg+=
"' at line "+QCString().setNum(md->
getDefLine())+
5593 if (root->
type!=
"friend class" &&
5594 root->
type!=
"friend struct" &&
5595 root->
type!=
"friend union" &&
5597 root->
type.find(
"typedef ")==-1)
5601 "documented symbol `%s' was not declared or defined.",decl
5609 const QList<ArgumentList> &srcTempArgLists,
5610 const QList<ArgumentList> &dstTempArgLists
5613 QListIterator<ArgumentList> srclali(srcTempArgLists);
5614 QListIterator<ArgumentList> dstlali(dstTempArgLists);
5615 for (;srclali.current();++srclali,++dstlali)
5619 if (!(sal && dal && sal->count()==dal->count()))
return TRUE;
5635 const QList<ArgumentList> &srcTempArgLists,
5636 const QList<ArgumentList> &dstTempArgLists,
5642 QRegExp re(
"[A-Za-z_][A-Za-z_0-9]*");
5645 while ((i=re.match(src,p,&l))!=-1)
5648 dst+=src.mid(p,i-p);
5649 QCString name=src.mid(i,l);
5651 QListIterator<ArgumentList> srclali(srcTempArgLists);
5652 QListIterator<ArgumentList> dstlali(dstTempArgLists);
5653 for (;srclali.current() && !found;++srclali,++dstlali)
5659 if (funcTempArgList)
5662 fa = fali->current();
5665 for (tsali.toFirst();(tsa=tsali.current()) && !found;++tsali)
5667 tda = tdali.current();
5671 if (name==tsa->
name)
5673 if (tda && tda->name.isEmpty())
5676 if (tda->type.left(6)==
"class ") vc=6;
5677 else if (tda->type.left(9)==
"typename ") vc=9;
5680 tda->name = tda->type.mid(vc);
5681 tda->type = tda->type.left(vc-1);
5684 if (tda && !tda->name.isEmpty())
5698 { ++(*fali); fa=fali->current(); }
5710 dst+=src.right(src.length()-p);
5717 const QList<ArgumentList> &srcTempArgLists,
5718 const QList<ArgumentList> &dstTempArgLists,
5729 for (sali.toFirst();(sa=sali.current());++sali)
5732 srcTempArgLists,dstTempArgLists,funcTempArgs,
5735 srcTempArgLists,dstTempArgLists,funcTempArgs,
5757 srcTempArgLists,dstTempArgLists,
5784 "findMember(root=%p,funcDecl=`%s',related=`%s',overload=%d,"
5785 "isFunc=%d mGrpId=%d tArgList=%p (#=%d) "
5786 "spec=%lld lang=%x\n",
5787 root,qPrint(funcDecl),qPrint(root->
relates),overloaded,isFunc,root->
mGrpId,
5794 QCString namespaceName;
5798 QCString funcTempList;
5799 QCString exceptions;
5801 bool isRelated=FALSE;
5802 bool isMemberOf=FALSE;
5803 bool isFriend=FALSE;
5808 if (funcDecl.stripPrefix(
"friend "))
5813 if (funcDecl.stripPrefix(
"inline "))
5818 if (funcDecl.stripPrefix(
"explicit "))
5823 if (funcDecl.stripPrefix(
"mutable "))
5828 if (funcDecl.stripPrefix(
"virtual "))
5836 while ((sep=funcDecl.find(
';'))!=-1)
5838 funcDecl=(funcDecl.left(sep)+funcDecl.right(funcDecl.length()-sep-1)).stripWhiteSpace();
5842 if (!funcDecl.isEmpty() && funcDecl[0]!=
' ') funcDecl.prepend(
" ");
5851 ).stripWhiteSpace();
5854 if (isFriend && funcDecl.left(6)==
"class ")
5857 funcDecl=funcDecl.right(funcDecl.length()-6);
5858 funcName = funcDecl.copy();
5860 else if (isFriend && funcDecl.left(7)==
"struct ")
5862 funcDecl=funcDecl.right(funcDecl.length()-7);
5863 funcName = funcDecl.copy();
5869 funcArgs,funcTempList,exceptions
5902 QCString joinedName = rootNav->
parent()->
name()+
"::"+scopeName;
5903 if (!scopeName.isEmpty() &&
5904 (
getClass(joinedName) || Doxygen::namespaceSDict->
find(joinedName)))
5906 scopeName = joinedName;
5921 QCString joinedName;
5924 for (nsdi.toFirst();(fnd=nsdi.current());++nsdi)
5926 joinedName = fnd->
name()+
"::"+scopeName;
5927 if (Doxygen::namespaceSDict->find(joinedName))
5929 scopeName=joinedName;
5959 if (namespaceName.find(
'@')!=-1)
return;
5963 scopeName.resize(0);
5964 if (!namespaceName.isEmpty())
5966 if (className.isEmpty())
5968 scopeName=namespaceName;
5970 else if (!root->
relates.isEmpty() ||
5973 scopeName=namespaceName+
"::"+className;
5977 scopeName=className;
5980 else if (!className.isEmpty())
5982 scopeName=className;
5986 QCString tempScopeName=scopeName;
5990 if (funcSpec.isEmpty())
5997 tempScopeName=scopeName+funcSpec;
6005 if (!scopeName.isEmpty() && !isRelated && !isFriend && !
Config_getBool(HIDE_SCOPE_NAMES))
6007 if (!funcType.isEmpty())
6011 funcDecl=funcType+
" "+tempScopeName+
"::"+funcName+funcTempList;
6015 funcDecl=funcType+
" "+tempScopeName+
"::"+funcName+funcArgs;
6022 funcDecl=tempScopeName+
"::"+funcName+funcTempList;
6026 funcDecl=tempScopeName+
"::"+funcName+funcArgs;
6032 if (!funcType.isEmpty())
6036 funcDecl=funcType+
" "+funcName+funcTempList;
6040 funcDecl=funcType+
" "+funcName+funcArgs;
6047 funcDecl=funcName+funcTempList;
6051 funcDecl=funcName+funcArgs;
6056 if (funcType==
"template class" && !funcTempList.isEmpty())
6060 "findMember() Parse results:\n"
6061 " namespaceName=`%s'\n"
6067 " funcTempList=`%s'\n"
6070 " exceptions=`%s'\n"
6075 qPrint(namespaceName),qPrint(className),
6076 qPrint(funcType),qPrint(funcSpec),qPrint(funcName),qPrint(funcArgs),qPrint(funcTempList),
6077 qPrint(funcDecl),qPrint(root->
relates),qPrint(exceptions),isRelated,isMemberOf,isFriend,
6082 if (!funcName.isEmpty())
6085 "1. funcName=`%s'\n",funcName.data());
6086 if (funcName.left(9)==
"operator ")
6088 funcName =
substitute(funcName,className+
"::",
"");
6090 if (!funcTempList.isEmpty())
6092 mn=Doxygen::memberNameSDict->
find(funcName+funcTempList);
6096 mn=Doxygen::memberNameSDict->
find(funcName);
6098 if (!isRelated && mn)
6101 "2. member name exists (%d members with this name)\n",mn->count());
6102 if (!className.isEmpty())
6104 if (funcSpec.isEmpty())
6110 bool memFound=FALSE;
6111 for (mni.toFirst();!memFound && (md=mni.current());++mni)
6115 "3. member definition found, "
6116 "scope needed=`%s' scope=`%s' args=`%s' fileName=%s\n",
6117 qPrint(scopeName),cd ? qPrint(cd->
name()) :
"<none>",
6118 qPrint(md->argsString()),
6140 "4. class definition %s found\n",cd->
name().data());
6143 QList<ArgumentList> declTemplArgs;
6148 declTemplArgs.append(templAl);
6152 QList<ArgumentList> *defTemplArgs = root->
tArgLists;
6156 bool substDone=FALSE;
6163 if (declTemplArgs.count()>0 && defTemplArgs &&
6164 declTemplArgs.count()==defTemplArgs->count() &&
6185 "5. matching `%s'<=>`%s' className=%s namespaceName=%s\n",
6187 qPrint(className),qPrint(namespaceName)
6191 md->isVariable() || md->isTypedef() ||
6192 (mdAl==0 && root->
argList->count()==0) ||
6194 md->getClassDef(),md->getFileDef(),argList,
6204 if (md->templateArguments()!=0 && root->
tArgLists!=0)
6206 QCString memType = md->typeString();
6207 memType.stripPrefix(
"static ");
6213 "5b. Comparing return types '%s'<->'%s' #args %d<->%d\n",
6214 qPrint(md->typeString()),qPrint(funcType),
6215 md->templateArguments()->count(),root->
tArgLists->getLast()->count());
6216 if (md->templateArguments()->count()!=root->
tArgLists->getLast()->count() ||
6217 qstrcmp(memType,funcType))
6225 bool mdIsTemplate = md->templateArguments()!=0;
6226 bool classOrMdIsTemplate = mdIsTemplate || classIsTemplate;
6227 bool rootIsTemplate = root->
tArgLists!=0;
6229 if (!rootIsUserDoc &&
6230 (mdIsTemplate || rootIsTemplate) &&
6231 ((classOrMdIsTemplate && !rootIsTemplate) || (!classOrMdIsTemplate && rootIsTemplate))
6237 "5b. Comparing return types: template v.s. non-template\n");
6243 "6. match results of matchArguments2 = %d\n",matching);
6249 md->setDefinitionTemplateParameterLists(root->
tArgLists);
6250 md->setArgumentList(argList);
6254 if (!funcTempList.isEmpty() &&
6276 else if (cd && cd!=tcd)
6282 if (count==0 && rootNav->
parent() &&
6285 goto localObjCMethod;
6287 if (count==0 && !(isFriend && funcType==
"class"))
6295 for (mni.toFirst();(md=mni.current());++mni)
6304 root->
tArgLists->getLast()->count()<=templAl->count())
6314 "7. new candidate className=%s scope=%s args=%s exact match\n",
6315 qPrint(className),qPrint(ccd->
name()),qPrint(md->argsString()));
6322 "7. new candidate className=%s scope=%s args=%s no match\n",
6323 qPrint(className),qPrint(ccd->
name()),qPrint(md->argsString()));
6329 static bool strictProtoMatching =
Config_getBool(STRICT_PROTO_MATCHING);
6330 if (!strictProtoMatching)
6332 if (candidates==1 && ucd && umd)
6339 else if (candidates>1 && ecd && emd)
6349 QCString warnMsg =
"no ";
6350 if (noMatchCount>1) warnMsg+=
"uniquely ";
6351 warnMsg+=
"matching class member found for \n";
6355 QListIterator<ArgumentList> alli(*root->
tArgLists);
6357 for (;(al=alli.current());++alli)
6359 warnMsg+=
" template ";
6364 QCString fullFuncDecl=funcDecl.copy();
6368 warnMsg+=fullFuncDecl;
6373 warnMsg+=
"Possible candidates:\n";
6374 for (mni.toFirst();(md=mni.current());++mni)
6382 warnMsg+=
" 'template ";
6387 if (md->typeString())
6389 warnMsg+=md->typeString();
6393 if (!qScope.isEmpty())
6394 warnMsg+=qScope+
"::"+md->name();
6395 if (md->argsString())
6396 warnMsg+=md->argsString();
6399 warnMsg+=
"' at line "+QCString().setNum(md->getDefLine()) +
6400 " of file "+md->getDefFileName();
6415 for (mni.toFirst();(md=mni.current());++mni)
6429 funcType,funcName,funcArgs,exceptions,
6432 mtype,tArgList,root->
argList);
6465 else if (overloaded)
6475 QCString className=cd->
name().copy();
6478 for (;(md=mni.current());++mni)
6481 if (className!=cd->
name()) unique=FALSE;
6497 funcType,funcName,funcArgs,exceptions,
6499 mtype,tArgList,root->
argList);
6500 md->setTagInfo(rootNav->
tagInfo());
6501 md->setLanguage(root->
lang);
6502 md->setId(root->
id);
6504 md->setMemberClass(cd);
6505 md->setDefinition(funcDecl);
6514 md->setDocsForDefinition(!root->
proto);
6515 md->setPrototype(root->
proto);
6516 md->addSectionsToDefinition(root->
anchors);
6520 md->setMemberSpecifiers(root->
spec);
6521 md->setMemberGroupId(root->
mGrpId);
6525 md->setRefItems(root->
sli);
6530 if (!
findGlobalMember(rootNav,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl))
6532 QCString fullFuncDecl=funcDecl.copy();
6535 "Cannot determine class for function\n%s",
6541 else if (isRelated && !root->
relates.isEmpty())
6544 " scopeName=%s className=%s\n",qPrint(scopeName),qPrint(className));
6545 if (className.isEmpty()) className=root->
relates;
6550 bool newMember=TRUE;
6551 bool newMemberName=FALSE;
6553 bool isDefine=FALSE;
6559 mdDefine = mni.current();
6560 while (mdDefine && !isDefine)
6562 isDefine = isDefine || mdDefine->
isDefine();
6563 if (!isDefine) { ++mni; mdDefine=mni.current(); }
6570 if ((mn=Doxygen::memberNameSDict->find(funcName))==0)
6579 while ((rmd=mni.current()) && newMember)
6588 if (newMember) ++mni;
6590 if (!newMember && rmd)
6612 if (isDefine && mdDefine)
6617 funcDecl=funcType +
" " + funcName;
6631 funcType,funcName,funcArgs,exceptions,
6633 root->
stat && !isMemberOf,
6637 funcArgs.isEmpty() ? 0 : root->
argList);
6639 if (isDefine && mdDefine)
6674 while ((rmd=rmni.current()) && !found)
6736 Doxygen::memberNameSDict->
append(funcName,mn);
6741 if (!
findGlobalMember(rootNav,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl))
6743 QCString fullFuncDecl=funcDecl.copy();
6746 "Cannot determine file/namespace for relatedalso function\n%s",
6755 "class `%s' for related function `%s' is not "
6757 className.data(),funcName.data()
6769 " scopeName=%s className=%s\n",qPrint(root->
name),qPrint(scopeName),qPrint(className));
6773 funcType,funcName,funcArgs,exceptions,
6798 if ((mn=Doxygen::memberNameSDict->find(root->
name)))
6806 Doxygen::memberNameSDict->
append(root->
name,mn);
6816 bool globMem =
findGlobalMember(rootNav,namespaceName,funcType,funcName,funcTempList,funcArgs,funcDecl);
6817 if (className.isEmpty() && !globMem)
6820 "class for member `%s' cannot "
6821 "be found.", funcName.data()
6824 else if (!className.isEmpty() && !globMem)
6827 "member `%s' of class `%s' cannot be found",
6828 funcName.data(),className.data());
6836 "member with no name found.");
6850 "findMemberDocumentation(): root->type=`%s' root->inside=`%s' root->name=`%s' root->args=`%s' section=%x root->spec=%lld root->mGrpId=%d\n",
6870 root->
args.prepend(root->
type.right(root->
type.length()-i-l));
6875 else if ((root->
type.left(8)==
"typedef " && root->
args.find(
'(')!=-1))
6887 if (root->
type.isEmpty())
6905 !root->
type.isEmpty() &&
6916 if (root->
type==
"friend class" || root->
type==
"friend struct" ||
6917 root->
type==
"friend union")
6925 else if (!root->
type.isEmpty())
6989 for (;(e=eli.current());++eli)
7004 for (;(objCImplNav=eli.current());++eli)
7010 for (;(objCMethodNav=seli.current());++seli)
7015 Entry *objCMethod = objCMethodNav->entry();
7018 findMember(objCMethodNav, objCMethod->
type+
" "+objCImplNav->name()+
"::"+
7019 objCMethod->
name+
" "+objCMethod->
args, FALSE,TRUE);
7022 objCMethodNav->releaseEntry();
7046 bool isRelated=FALSE;
7047 bool isMemberOf=FALSE;
7054 if ((i=root->
name.findRev(
"::"))!=-1)
7056 scope=root->
name.left(i);
7057 name=root->
name.right(root->
name.length()-i-2);
7083 if (cd && !name.isEmpty())
7090 else if (nd && !nd->
name().isEmpty() && nd->
name().at(0)!=
'@')
7102 if (!name.isEmpty())
7131 QCString baseType = root->
args;
7132 if (!baseType.isEmpty())
7134 baseType.prepend(
" : ");
7137 if (nd && !nd->
name().isEmpty() && nd->
name().at(0)!=
'@')
7159 if (fd==0 && rootNav->
parent())
7189 if ((mn=(*mnsd)[name]))
7227 bool isRelated=FALSE;
7234 if ((i=root->
name.findRev(
"::"))!=-1)
7236 scope=root->
name.left(i);
7237 name=root->
name.right(root->
name.length()-i-2);
7262 if (cd && !name.isEmpty())
7269 else if (nd && !nd->
name().isEmpty() && nd->
name().at(0)!=
'@')
7283 if (!name.isEmpty())
7291 for (mni.toFirst(); (md=mni.current()) ; ++mni)
7298 for (;(e=eli.current());++eli)
7311 e->loadEntry(g_storage);
7312 Entry *root = e->entry();
7316 if (!scope.isEmpty() && rootNav->
tagInfo())
7318 qualifiedName=
substitute(scope,
"::",
".")+
"."+qualifiedName;
7324 QCString fileName = root->
fileName;
7325 if (fileName.isEmpty() && rootNav->
tagInfo())
7370 MemberNameSDict *emnsd = isRelated ? Doxygen::functionNameSDict : mnsd;
7371 if (!e->name().isEmpty() && (fmn=(*emnsd)[e->name()]))
7376 for (fmni.toFirst(); (fmd=fmni.current()) ; ++fmni)
7382 if (nd && !nd->
name().isEmpty() && nd->
name().at(0)!=
'@')
7400 else if (isRelated && cd)
7446 && !rootNav->
name().isEmpty()
7447 && rootNav->
name().at(0)!=
'@'
7458 if ((i=root->
name.findRev(
"::"))!=-1)
7460 name=root->
name.right(root->
name.length()-i-2);
7461 scope=root->
name.left(i);
7472 if (!scope.isEmpty()) scope.prepend(
"::");
7477 if (!name.isEmpty())
7483 QCString className=cd->
name().copy();
7489 for (mni.toFirst();(md=mni.current()) && !found;++mni)
7526 if (gd==0 &&root->
groups->getFirst()!=0)
7548 for (mni.toFirst();(md=mni.current()) && !found;++mni)
7560 if (gd==0 && root->
groups->getFirst()!=0)
7573 "Documentation for undefined enum `%s' found.",
7591 for (mnli.toFirst();(mn=mnli.current());++mnli)
7596 for (mni.toFirst();(md=mni.current());++mni)
7601 int documentedEnumValues=0;
7607 for (fmni.toFirst();(fmd=fmni.current());++fmni)
7623 findDEV(*Doxygen::memberNameSDict);
7624 findDEV(*Doxygen::functionNameSDict);
7634 for (mnli.toFirst();(mn=mnli.current());++mnli)
7639 for (mni.toFirst();(md=mni.current());++mni)
7646 for (fnli.toFirst();(mn=fnli.current());++fnli)
7651 for (mni.toFirst();(md=mni.current());++mni)
7674 for ( ; (mn=mnli.current()) ; ++mnli )
7680 for ( ; (md=mdi.current()) ; ++mdi )
7682 for ( bmdi.toFirst() ; (bmd=bmdi.current()); ++bmdi )
7692 if (md!=bmd && bmcd && mcd && bmcd!=mcd &&
7753 for (cli.toFirst();(cd=cli.current());++cli)
7759 QDictIterator<ClassDef> qdi(*templInstances);
7762 for (qdi.toFirst();(tcd=qdi.current());++qdi)
7777 for (cli.toFirst();(cd=cli.current());++cli)
7779 int i=cd->
name().find(
'(');
7782 QCString baseName=cd->
name().left(i);
7783 ClassDef *baseClass=Doxygen::classSDict->
find(baseName);
7801 for (cli.toFirst();(cd=cli.current());++cli)
7812 for (cli.toFirst();(cd=cli.current());++cli)
7822 if (Doxygen::inputNameList->count()>0)
7825 static bool clangAssistedParsing =
Config_getBool(CLANG_ASSISTED_PARSING);
7826 if (clangAssistedParsing)
7828 QDict<void> g_processedFiles(10007);
7831 QDict<void> g_filesToProcess(10007);
7834 for (fnli.toFirst();(fn=fnli.current());++fnli)
7838 for (;(fd=fni.current());++fni)
7840 g_filesToProcess.insert(fd->
absFilePath(),(
void*)0x8);
7844 for (fnli.toFirst();(fn=fnli.current());++fnli)
7848 for (;(fd=fni.current());++fni)
7852 QStrList filesInSameTu;
7857 msg(
"Generating code for file %s...\n",fd->
docName().data());
7858 fd->
writeSource(*g_outputList,FALSE,filesInSameTu);
7864 msg(
"Parsing code for file %s...\n",fd->
docName().data());
7868 char *incFile = filesInSameTu.first();
7869 while (incFile && g_filesToProcess.find(incFile))
7871 if (fd->
absFilePath()!=incFile && !g_processedFiles.find(incFile))
7880 msg(
" Generating code for file %s...\n",ifd->
docName().data());
7887 msg(
" Parsing code for file %s...\n",ifd->
docName().data());
7890 g_processedFiles.insert(incFile,(
void*)0x8);
7893 incFile = filesInSameTu.next();
7896 g_processedFiles.insert(fd->
absFilePath(),(
void*)0x8);
7901 for (fnli.toFirst();(fn=fnli.current());++fnli)
7905 for (;(fd=fni.current());++fni)
7909 QStrList filesInSameTu;
7913 msg(
"Generating code for file %s...\n",fd->
docName().data());
7914 fd->
writeSource(*g_outputList,FALSE,filesInSameTu);
7920 msg(
"Parsing code for file %s...\n",fd->
docName().data());
7933 for (;(fn=fnli.current());++fnli)
7937 for (;(fd=fni.current());++fni)
7939 QStrList filesInSameTu;
7943 msg(
"Generating code for file %s...\n",fd->
docName().data());
7944 fd->
writeSource(*g_outputList,FALSE,filesInSameTu);
7950 msg(
"Parsing code for file %s...\n",fd->
docName().data());
7966 if (Doxygen::inputNameList->count()>0)
7970 for (fnli.toFirst();(fn=fnli.current());++fnli)
7974 for (fni.toFirst();(fd=fni.current());++fni)
7979 msg(
"Generating docs for file %s...\n",fd->
docName().data());
7994 for (cli.toFirst();(cd=cli.current());++cli)
8005 for (nli.toFirst();(nd=nli.current());++nli)
8017 for (mnli.toFirst();(mn=mnli.current());++mnli)
8021 for (mni.toFirst();(md=mni.current());++mni)
8041 for (fnli.toFirst();(mn=fnli.current());++fnli)
8045 for (mni.toFirst();(md=mni.current());++mni)
8074 for (cli.toFirst();(cd=cli.current());++cli)
8082 for (nli.toFirst();(nd=nli.current());++nli)
8090 for (;(fn=fnli.current());++fnli)
8094 for (;(fd=fni.current());++fni)
8103 for (gli.toFirst();(gd=gli.current());++gli)
8115 for ( ; cli.current() ; ++cli )
8130 msg(
"Generating docs for compound %s...\n",cd->
name().data());
8154 for (;(mn=mnli.current());++mnli)
8158 for (;(md=mni.current());++mni)
8192 for (fnli.toFirst();(fn=fnli.current());++fnli)
8196 for (fni.toFirst();(fd=fni.current());++fni)
8201 for (fnli.toFirst();(fn=fnli.current());++fnli)
8205 for (fni.toFirst();(fd=fni.current());++fni)
8214 for (nli.toFirst() ; (nd=nli.current()) ; ++nli )
8218 for (nli.toFirst() ; (nd=nli.current()) ; ++nli )
8231 for ( ; (cd=cli.current()) ; ++cli )
8238 for (fnli.toFirst();(fn=fnli.current());++fnli)
8242 for (fni.toFirst();(fd=fni.current());++fni)
8250 for ( ; (nd=nli.current()) ; ++nli )
8257 for (gli.toFirst();(gd=gli.current());++gli)
8270 for ( ; (cd=cli.current()) ; ++cli )
8277 for (fnli.toFirst();(fn=fnli.current());++fnli)
8281 for (fni.toFirst();(fd=fni.current());++fni)
8289 for ( ; (nd=nli.current()) ; ++nli )
8296 for (gli.toFirst();(gd=gli.current());++gli)
8309 for ( ; (cd=cli.current()) ; ++cli )
8316 for (fnli.toFirst();(fn=fnli.current());++fnli)
8320 for (fni.toFirst();(fd=fni.current());++fni)
8328 for ( ; (nd=nli.current()) ; ++nli )
8335 for (gli.toFirst();(gd=gli.current());++gli)
8342 for (pdi.toFirst();(pd=pdi.current());++pdi)
8357 for (ci.toFirst();(li=ci.current());++ci)
8368 for (;(fn=fnli.current());++fnli)
8372 for (;(fmd=fni.current());++fni)
8382 for (;(fn=mnli.current());++mnli)
8386 for (;(fmd=mni.current());++mni)
8413 for (ci.toFirst();(li=ci.current());++ci)
8423 for (;(fn=fnli.current());++fnli)
8427 for (;(fmd=fni.current());++fni)
8433 for (;(fn=mnli.current());++mnli)
8437 for (;(fmd=mni.current());++mni)
8470 if ((mn=Doxygen::functionNameSDict->find(root->
name)))
8478 Doxygen::functionNameSDict->
append(root->
name,mn);
8487 for (;(md=mni.current());++mni)
8493 for (mni.toFirst();(md=mni.current());++mni)
8515 (!root->
doc.isEmpty() ||
8516 !root->
brief.isEmpty() ||
8523 for (mni.toFirst();(md=mni.current());++mni)
8564 else if (!root->
doc.isEmpty() || !root->
brief.isEmpty())
8570 "documentation for unknown define %s found.\n",
8577 "found documented #define but ignoring it because "
8578 "ENABLE_PREPROCESSING is NO.\n",
8598 QCString normalizedName = root->
name;
8599 normalizedName =
substitute(normalizedName,
"\\",
"/");
8602 if (root->
docFile==normalizedName)
8604 int lastSlashPos=normalizedName.findRev(
'/');
8605 if (lastSlashPos!=-1)
8607 normalizedName=normalizedName.left(lastSlashPos);
8610 if (normalizedName.at(normalizedName.length()-1)!=
'/')
8612 normalizedName+=
'/';
8614 DirDef *dir,*matchingDir=0;
8616 for (sdi.toFirst();(dir=sdi.current());++sdi)
8619 if (dir->
name().right(normalizedName.length())==normalizedName)
8624 "\\dir command matches multiple directories.\n"
8625 " Applying the command for directory %s\n"
8626 " Ignoring the command for directory %s\n",
8627 matchingDir->
name().data(),dir->
name().data()
8647 "directory found for command \\dir %s\n",normalizedName.data());
8665 if (!root->
name.isEmpty())
8677 QCString title=root->
args.stripWhiteSpace();
8680 QCString name =
"index";
8701 if (Doxygen::mainPage==0 && rootNav->
tagInfo()==0)
8705 QCString title=root->
args.stripWhiteSpace();
8707 QCString indexName=
"index";
8716 SectionInfo *si = Doxygen::sectionDict->
find(Doxygen::mainPage->name());
8725 warn(root->
fileName,root->
startLine,
"multiple use of section label '%s' for main page, (first occurrence: %s)",Doxygen::mainPage->
name().data(),si->
fileName.data());
8733 Doxygen::mainPage->
name(),
8734 Doxygen::mainPage->
title(),
8737 Doxygen::sectionDict->
append(indexName,si);
8741 else if (rootNav->
tagInfo()==0)
8745 "found more than one \\mainpage comment block! (first occurrence: %s, line %d), Skipping current block!",
8746 Doxygen::mainPage->
docFile().data(),Doxygen::mainPage->
docLine());
8761 if (Doxygen::mainPage && rootNav->
tagInfo())
8775 && !rootNav->
name().isEmpty()
8782 Doxygen::pageSDict->
find(root->
name) :
8786 QListIterator<BaseInfo> bii(*root->
extends);
8788 for (bii.toFirst();(bi=bii.current());++bii)
8809 for (pdi.toFirst();(pd=pdi.current());++pdi)
8816 err(
"page defined at line %d of file %s with label %s is a subpage "
8817 "of itself! Please remove this cyclic dependency.\n",
8832 for (;(si=sdi.current());++sdi)
8846 for (rli.toFirst();(rl=rli.current());++rli)
8849 if (si->
label.left(label.length())==label)
8906 for (pdi.toFirst();(pd=pdi.current());++pdi)
8910 msg(
"Generating docs for page %s...\n",pd->
name().data());
8913 Doxygen::insideMainPage=FALSE;
8928 if (Doxygen::exampleSDict->find(root->
name))
8931 "Example %s was already documented. Ignoring "
8932 "documentation found here.",
8946 Doxygen::exampleSDict->
inSort(root->
name,pd);
8962 indentStr.fill(
' ',indent);
8963 msg(
"%s%s (sec=0x%x)\n",
8964 indentStr.isEmpty()?
"":indentStr.data(),
8965 rootNav->
name().isEmpty()?
"<empty>":rootNav->
name().data(),
8970 for (;eli.current();++eli)
printNavTree(eli.current(),indent+2);
8983 for (pdi.toFirst();(pd=pdi.current());++pdi)
8985 msg(
"Generating docs for example %s...\n",pd->
name().data());
9014 for (gli.toFirst();(gd=gli.current());++gli)
9050 for (;(nd=nli.current());++nli)
9055 msg(
"Generating docs for namespace %s\n",nd->
name().data());
9062 for ( ; (cd=cli.current()) ; ++cli )
9064 if ( ( cd->isLinkableInProject() &&
9065 cd->templateMaster()==0
9068 && !cd->isHidden() && !cd->isEmbeddedInOuterScope()
9071 msg(
"Generating docs for compound %s...\n",cd->name().data());
9073 cd->writeDocumentation(*g_outputList);
9074 cd->writeMemberList(*g_outputList);
9076 cd->writeDocumentationForInnerClasses(*g_outputList);
9082 static QCString fixSlashes(QCString &s)
9086 for (i=0;i<s.length();i++)
9110 bool updateOnly=FALSE)
9114 bool writeToStdout=(configFile[0]==
'-' && configFile[1]==
'\0');
9123 msg(
"\n\nConfiguration file `%s' created.\n\n",configFile);
9124 msg(
"Now edit the configuration file and enter\n\n");
9125 if (qstrcmp(configFile,
"Doxyfile") || qstrcmp(configFile,
"doxyfile"))
9126 msg(
" doxygen %s\n\n",configFile);
9128 msg(
" doxygen\n\n");
9129 msg(
"to generate the documentation for your project\n\n");
9133 msg(
"\n\nConfiguration file `%s' updated.\n\n",configFile);
9139 err(
"Cannot open file %s for writing\n",configFile);
9159 QCString tagLine = tl;
9162 int eqPos = tagLine.find(
'=');
9165 fileName = tagLine.left(eqPos).stripWhiteSpace();
9166 destName = tagLine.right(tagLine.length()-eqPos-1).stripWhiteSpace();
9167 QFileInfo fi(fileName);
9176 QFileInfo fi(fileName);
9177 if (!fi.exists() || !fi.isFile())
9179 err(
"Tag file `%s' does not exist or is not a file. Skipping it...\n",
9184 if (!destName.isEmpty())
9185 msg(
"Reading tag file `%s', location `%s'...\n",fileName.data(),destName.data());
9187 msg(
"Reading tag file `%s'...\n",fileName.data());
9195 QStrList latexExtraStyleSheet =
Config_getList(LATEX_EXTRA_STYLESHEET);
9196 for (uint i=0; i<latexExtraStyleSheet.count(); ++i)
9198 QCString fileName(latexExtraStyleSheet.at(i));
9199 if (!fileName.isEmpty())
9201 QFileInfo fi(fileName);
9204 err(
"Style sheet '%s' specified by LATEX_EXTRA_STYLESHEET does not exist!\n",fileName.data());
9208 QCString destFileName =
Config_getString(LATEX_OUTPUT)+
"/"+fi.fileName().data();
9223 if (!htmlStyleSheet.isEmpty())
9225 QFileInfo fi(htmlStyleSheet);
9228 err(
"Style sheet '%s' specified by HTML_STYLESHEET does not exist!\n",htmlStyleSheet.data());
9229 htmlStyleSheet.resize(0);
9233 QCString destFileName =
Config_getString(HTML_OUTPUT)+
"/"+fi.fileName().data();
9234 copyFile(htmlStyleSheet,destFileName);
9237 QStrList htmlExtraStyleSheet =
Config_getList(HTML_EXTRA_STYLESHEET);
9238 for (uint i=0; i<htmlExtraStyleSheet.count(); ++i)
9240 QCString fileName(htmlExtraStyleSheet.at(i));
9241 if (!fileName.isEmpty())
9243 QFileInfo fi(fileName);
9246 err(
"Style sheet '%s' specified by HTML_EXTRA_STYLESHEET does not exist!\n",fileName.data());
9248 else if (fi.fileName()==
"doxygen.css" || fi.fileName()==
"tabs.css" || fi.fileName()==
"navtree.css")
9250 err(
"Style sheet %s specified by HTML_EXTRA_STYLESHEET is already a built-in stylesheet. Please use a different name\n",fi.fileName().data());
9254 QCString destFileName =
Config_getString(HTML_OUTPUT)+
"/"+fi.fileName().data();
9264 if (!projectLogo.isEmpty())
9266 QFileInfo fi(projectLogo);
9269 err(
"Project logo '%s' specified by PROJECT_LOGO does not exist!\n",projectLogo.data());
9270 projectLogo.resize(0);
9274 QCString destFileName = outputOption+
"/"+fi.fileName().data();
9275 copyFile(projectLogo,destFileName);
9276 Doxygen::indexList->
addImageFile(fi.fileName().data());
9284 for (i=0; i<files.count(); ++i)
9286 QCString fileName(files.at(i));
9288 if (!fileName.isEmpty())
9290 QFileInfo fi(fileName);
9293 err(
"Extra file '%s' specified in %s does not exist!\n", fileName.data(),filesOption.data());
9297 QCString destFileName = outputOption+
"/"+fi.fileName().data();
9298 Doxygen::indexList->
addImageFile(fi.fileName().utf8());
9309 QCString fileName=fn;
9311 int sep = fileName.findRev(
'/');
9312 int ei = fileName.findRev(
'.');
9313 if (ei!=-1 && (sep==-1 || ei>sep))
9315 extension=fileName.right(fileName.length()-ei);
9319 extension =
".no_extension";
9322 return Doxygen::parserManager->
getParser(extension);
9327 bool sameTu,QStrList &filesInSameTu)
9330 static bool clangAssistedParsing =
Config_getBool(CLANG_ASSISTED_PARSING);
9332 static bool clangAssistedParsing = FALSE;
9334 QCString fileName=fn;
9336 int ei = fileName.findRev(
'.');
9339 extension=fileName.right(fileName.length()-ei);
9343 extension =
".no_extension";
9346 QFileInfo fi(fileName);
9347 BufStr preBuf(fi.size()+4096);
9352 BufStr inBuf(fi.size()+4096);
9353 msg(
"Preprocessing %s...\n",fn);
9359 msg(
"Reading %s...\n",fn);
9362 if (preBuf.data() && preBuf.curPos()>0 && *(preBuf.data()+preBuf.curPos()-1)!=
'\n')
9364 preBuf.addChar(
'\n');
9367 BufStr convBuf(preBuf.curPos()+1024);
9372 convBuf.addChar(
'\0');
9374 if (clangAssistedParsing && !sameTu)
9380 parser->
parseInput(fileName,convBuf.data(),root,sameTu,filesInSameTu);
9392 static bool clangAssistedParsing =
Config_getBool(CLANG_ASSISTED_PARSING);
9393 if (clangAssistedParsing)
9395 QDict<void> g_processedFiles(10007);
9398 QDict<void> g_filesToProcess(10007);
9401 for (;(s=it.current());++it)
9403 g_filesToProcess.insert(*s,(
void*)0x8);
9407 for (it.toFirst();(s=it.current());++it)
9414 QStrList filesInSameTu;
9417 parseFile(parser,root,rootNav,fd,s->data(),FALSE,filesInSameTu);
9422 char *incFile = filesInSameTu.first();
9423 while (incFile && g_filesToProcess.find(incFile))
9425 if (qstrcmp(incFile,s->data()) && !g_processedFiles.find(incFile))
9432 parseFile(parser,root,rootNav,ifd,incFile,TRUE,moreFiles);
9433 g_processedFiles.insert(incFile,(
void*)0x8);
9436 incFile = filesInSameTu.next();
9439 g_processedFiles.insert(*s,(
void*)0x8);
9443 for (it.toFirst();(s=it.current());++it)
9445 if (!g_processedFiles.find(*s))
9448 QStrList filesInSameTu;
9453 parseFile(parser,root,rootNav,fd,s->data(),FALSE,filesInSameTu);
9455 g_processedFiles.insert(*s,(
void*)0x8);
9464 for (;(s=it.current());++it)
9467 QStrList filesInSameTu;
9472 parseFile(parser,root,rootNav,fd,s->data(),FALSE,filesInSameTu);
9484 QDict<void> nonSymlinks;
9486 QCString result = path;
9487 QCString oldPrefix =
"/";
9492 if (sepPos==0 && (result.left(2)==
"//" || result.left(2)==
"\\\\"))
9493 sepPos = result.find(
'/',2);
9495 sepPos = result.find(
'/',sepPos+1);
9497 sepPos = result.find(
'/',sepPos+1);
9499 QCString prefix = sepPos==-1 ? result : result.left(sepPos);
9500 if (nonSymlinks.find(prefix)==0)
9505 QString target = fi.readLink();
9506 bool isRelative = QFileInfo(target).isRelative();
9509 target = QDir::cleanDirPath(oldPrefix+
"/"+target.data());
9513 if (fi.isDir() && target.length()>0 && target.at(target.length()-1)!=
'/')
9517 target+=result.mid(sepPos);
9519 result = QDir::cleanDirPath(target).data();
9521 if (known.find(result))
return QCString();
9522 known.insert(result,(
void*)0x8);
9535 nonSymlinks.insert(prefix,(
void*)0x8);
9542 return QDir::cleanDirPath(result).data();
9558 QStrList *exclPatList,
9561 bool errorIfNotExist,
9563 QDict<void> *killDict,
9567 QCString dirName = fi->absFilePath().utf8();
9568 if (paths && paths->find(dirName)==0)
9570 paths->insert(dirName,(
void*)0x8);
9572 if (fi->isSymLink())
9575 if (dirName.isEmpty())
return 0;
9580 dir.setFilter( QDir::Files | QDir::Dirs | QDir::Hidden );
9582 msg(
"Searching for files in directory %s\n", fi->absFilePath().data());
9585 const QFileInfoList *list = dir.entryInfoList();
9588 QFileInfoListIterator it( *list );
9591 while ((cfi=it.current()))
9593 if (exclDict==0 || exclDict->find(cfi->absFilePath().utf8())==0)
9596 if (!cfi->exists() || !cfi->isReadable())
9598 if (errorIfNotExist)
9600 warn_uncond(
"source %s is not a readable file or directory... skipping.\n",cfi->absFilePath().data());
9603 else if (cfi->isFile() &&
9607 (killDict==0 || killDict->find(cfi->absFilePath().utf8())==0)
9610 totalSize+=cfi->size()+cfi->absFilePath().length()+4;
9611 QCString name=cfi->fileName().utf8();
9617 if (!name.isEmpty() && (fn=(*fnDict)[name]))
9623 fn =
new FileName(cfi->absFilePath().utf8(),name);
9625 if (fnList) fnList->inSort(fn);
9626 fnDict->insert(name,fn);
9630 if (resultList || resultDict)
9632 rs=
new QCString(cfi->absFilePath().utf8());
9634 if (resultList) resultList->append(rs);
9635 if (resultDict) resultDict->insert(cfi->absFilePath().utf8(),rs);
9636 if (killDict) killDict->insert(cfi->absFilePath().utf8(),(
void *)0x8);
9638 else if (recursive &&
9642 cfi->fileName().at(0)!=
'.')
9644 cfi->setFile(cfi->absFilePath());
9645 totalSize+=
readDir(cfi,fnList,fnDict,exclDict,
9646 patList,exclPatList,resultList,resultDict,errorIfNotExist,
9647 recursive,killDict,paths);
9666 QStrList *exclPatList,
9670 bool errorIfNotExist,
9671 QDict<void> *killDict,
9679 char lc = fs.at(fs.length()-1);
9680 if (lc==
'/' || lc==
'\\') fs = fs.left(fs.length()-1);
9686 if (exclDict==0 || exclDict->find(fi.absFilePath().utf8())==0)
9688 if (!fi.exists() || !fi.isReadable())
9690 if (errorIfNotExist)
9692 warn_uncond(
"source %s is not a readable file or directory... skipping.\n",s);
9699 QCString dirPath = fi.dirPath(TRUE).utf8();
9700 QCString filePath = fi.absFilePath().utf8();
9701 if (paths && paths->find(dirPath))
9703 paths->insert(dirPath,(
void*)0x8);
9706 if (killDict==0 || killDict->find(filePath)==0)
9708 totalSize+=fi.size()+fi.absFilePath().length()+4;
9710 QCString name=fi.fileName().utf8();
9716 if (!name.isEmpty() && (fn=(*fnDict)[name]))
9724 if (fnList) fnList->inSort(fn);
9725 fnDict->insert(name,fn);
9729 if (resultList || resultDict)
9731 rs=
new QCString(filePath);
9732 if (resultList) resultList->append(rs);
9733 if (resultDict) resultDict->insert(filePath,rs);
9736 if (killDict) killDict->insert(fi.absFilePath().utf8(),(
void *)0x8);
9739 else if (fi.isDir())
9741 totalSize+=
readDir(&fi,fnList,fnDict,exclDict,patList,
9742 exclPatList,resultList,resultDict,errorIfNotExist,
9743 recursive,killDict,paths);
9756 if (f.open(IO_ReadOnly))
9758 msg(
"Reading formula repository...\n");
9763 line=t.readLine().utf8();
9764 int se=line.find(
':');
9767 warn_uncond(
"formula.repository is corrupted!\n");
9772 QCString formName = line.left(se);
9773 QCString formText = line.right(line.length()-se-1);
9775 Doxygen::formulaList->setAutoDelete(TRUE);
9776 Doxygen::formulaList->append(f);
9777 Doxygen::formulaDict->insert(formText,f);
9778 Doxygen::formulaNameDict->insert(formName,f);
9790 for (adi.toFirst();(s=adi.current());++adi)
9802 for (adi.toFirst();(s=adi.current());++adi)
9804 QCString value=*s,newValue;
9807 while ((in=value.find(
"\\n",p))!=-1)
9809 newValue+=value.mid(p,in-p);
9811 if (value.mid(in,5)!=
"\\note" &&
9812 value.mid(in,5)!=
"\\name" &&
9813 value.mid(in,10)!=
"\\namespace" &&
9814 value.mid(in,14)!=
"\\nosubgrouping"
9817 newValue+=
"\\_linebr ";
9825 newValue+=value.mid(p,value.length()-p);
9838 const char *s=aliasList.first();
9844 int i=alias.find(
'=');
9847 QCString name=alias.left(i).stripWhiteSpace();
9848 QCString value=alias.right(alias.length()-i-1);
9850 if (!name.isEmpty())
9885 t <<
"REPLACE INTO symbols (symbol_id,scope_id,name,file,line) VALUES('"
9888 << d->
name() <<
"','"
9896 QFile f(
"symbols.sql");
9897 if (f.open(IO_WriteOnly))
9902 for (;(intf=di.current());++di)
9909 for (dli.toFirst();(d=dli.current());++dli)
9917 if (d!=Doxygen::globalScope)
dumpSymbol(t,d);
9926 msg(
"Developer parameters:\n");
9927 msg(
" -m dump symbol map\n");
9928 msg(
" -b output to wizard\n");
9929 msg(
" -T activates output generation via Django like template\n");
9930 msg(
" -d <level> enable a debug level, such as (multiple invocations of -d are possible):\n");
9940 msg(
"Doxygen version %s\nCopyright Dimitri van Heesch 1997-2015\n\n",
versionString);
9941 msg(
"You can use doxygen in a number of ways:\n\n");
9942 msg(
"1) Use doxygen to generate a template configuration file:\n");
9943 msg(
" %s [-s] -g [configName]\n\n",name);
9944 msg(
" If - is used for configName doxygen will write to standard output.\n\n");
9945 msg(
"2) Use doxygen to update an old configuration file:\n");
9946 msg(
" %s [-s] -u [configName]\n\n",name);
9947 msg(
"3) Use doxygen to generate documentation using an existing ");
9948 msg(
"configuration file:\n");
9949 msg(
" %s [configName]\n\n",name);
9950 msg(
" If - is used for configName doxygen will read from standard input.\n\n");
9951 msg(
"4) Use doxygen to generate a template file controlling the layout of the\n");
9952 msg(
" generated documentation:\n");
9953 msg(
" %s -l [layoutFileName.xml]\n\n",name);
9954 msg(
"5) Use doxygen to generate a template style sheet file for RTF, HTML or Latex.\n");
9955 msg(
" RTF: %s -w rtf styleSheetFile\n",name);
9956 msg(
" HTML: %s -w html headerFile footerFile styleSheetFile [configFile]\n",name);
9957 msg(
" LaTeX: %s -w latex headerFile footerFile styleSheetFile [configFile]\n\n",name);
9958 msg(
"6) Use doxygen to generate a rtf extensions file\n");
9959 msg(
" RTF: %s -e rtf extensionsFile\n\n",name);
9960 msg(
"If -s is specified the comments of the configuration items in the config file will be omitted.\n");
9961 msg(
"If configName is omitted `Doxyfile' will be used as a default.\n\n");
9962 msg(
"-v print version string\n");
9969 static const char *
getArg(
int argc,
char **argv,
int &optind)
9972 if (qstrlen(&argv[optind][2])>0)
9974 else if (optind+1<argc && argv[optind+1][0]!=
'-')
9986 setlocale(LC_ALL,
"");
9987 setlocale(LC_CTYPE,
"C");
9988 setlocale(LC_NUMERIC,
"C");
10013 #ifdef USE_LIBCLANG
10017 Doxygen::inputNameList->setAutoDelete(TRUE);
10028 Doxygen::hiddenClasses =
new ClassSDict(257);
10030 Doxygen::directories =
new DirSDict(17);
10032 Doxygen::pageSDict =
new PageSDict(1009);
10034 Doxygen::exampleSDict =
new PageSDict(1009);
10039 Doxygen::citeDict =
new CiteDict(257);
10044 Doxygen::formulaNameDict =
new FormulaDict(1009);
10050 Doxygen::globalScope = 0;
10051 Doxygen::inputNameDict = 0;
10052 Doxygen::includeNameDict = 0;
10053 Doxygen::exampleNameDict = 0;
10054 Doxygen::imageNameDict = 0;
10055 Doxygen::dotFileNameDict = 0;
10056 Doxygen::mscFileNameDict = 0;
10057 Doxygen::diaFileNameDict = 0;
10106 for (dli.toFirst();(di=dli.current());)
10140 while (v!=0) v>>=1,r++;
10144 return QMAX(0,QMIN(r-16,9));
10154 const char *configName=0;
10155 const char *layoutName=0;
10156 const char *debugLabel;
10157 const char *formatName;
10158 bool genConfig=FALSE;
10159 bool shortList=FALSE;
10160 bool updateConfig=FALSE;
10161 bool genLayout=FALSE;
10163 while (optind<argc && argv[optind][0]==
'-' &&
10164 (isalpha(argv[optind][1]) || argv[optind][1]==
'?' ||
10165 argv[optind][1]==
'-')
10168 switch(argv[optind][1])
10172 configName=
getArg(argc,argv,optind);
10173 if (optind+1<argc && qstrcmp(argv[optind+1],
"-")==0)
10174 { configName=
"-"; optind++; }
10176 { configName=
"Doxyfile"; }
10180 layoutName=
getArg(argc,argv,optind);
10182 { layoutName=
"DoxygenLayout.xml"; }
10185 debugLabel=
getArg(argc,argv,optind);
10188 err(
"option \"-d\" is missing debug specifier.\n");
10196 err(
"option \"-d\" has unknown debug specifier: \"%s\".\n",debugLabel);
10208 formatName=
getArg(argc,argv,optind);
10211 err(
"option \"-e\" is missing format specifier rtf.\n");
10215 if (qstricmp(formatName,
"rtf")==0)
10217 if (optind+1>=argc)
10219 err(
"option \"-e rtf\" is missing an extensions file name\n");
10231 err(
"option \"-e\" has invalid format specifier.\n");
10236 formatName=
getArg(argc,argv,optind);
10239 err(
"option \"-w\" is missing format specifier rtf, html or latex\n");
10243 if (qstricmp(formatName,
"rtf")==0)
10245 if (optind+1>=argc)
10247 err(
"option \"-w rtf\" is missing a style sheet file name\n");
10259 else if (qstricmp(formatName,
"html")==0)
10262 if (optind+4<argc || QFileInfo(
"Doxyfile").exists())
10265 QCString df = optind+4<argc ? argv[optind+4] : QCString(
"Doxyfile");
10268 err(
"error opening or reading configuration file %s!\n",argv[optind+4]);
10273 if (optind+3>=argc)
10275 err(
"option \"-w html\" does not have enough arguments\n");
10285 warn_uncond(
"Output language %s not supported! Using English instead.\n", outputLanguage.data());
10306 else if (qstricmp(formatName,
"latex")==0)
10309 if (optind+4<argc || QFileInfo(
"Doxyfile").exists())
10311 QCString df = optind+4<argc ? argv[optind+4] : QCString(
"Doxyfile");
10314 err(
"error opening or reading configuration file %s!\n",argv[optind+4]);
10319 if (optind+3>=argc)
10321 err(
"option \"-w latex\" does not have enough arguments\n");
10331 warn_uncond(
"Output language %s not supported! Using English instead.\n", outputLanguage.data());
10354 err(
"Illegal format specifier \"%s\": should be one of rtf, html or latex\n",formatName);
10368 if (qstrcmp(&argv[optind][2],
"help")==0)
10373 else if (qstrcmp(&argv[optind][2],
"version")==0)
10381 err(
"Unknown option \"-%s\"\n",&argv[optind][1]);
10387 setvbuf(stdout,NULL,_IONBF,0);
10391 msg(
"Warning: this option activates output generation via Django like template files. "
10392 "This option is scheduled for doxygen 2.0, is currently incomplete and highly experimental! "
10393 "Only use if you are a doxygen developer\n");
10402 err(
"Unknown option \"-%c\"\n",argv[optind][1]);
10435 QFileInfo configFileInfo1(
"Doxyfile"),configFileInfo2(
"doxyfile");
10438 if (configFileInfo1.exists())
10440 configName=
"Doxyfile";
10442 else if (configFileInfo2.exists())
10444 configName=
"doxyfile";
10448 err(
"Doxyfile not found and no input file specified!\n");
10455 QFileInfo fi(argv[optind]);
10456 if (fi.exists() || qstrcmp(argv[optind],
"-")==0)
10458 configName=argv[optind];
10462 err(
"configuration file %s not found!\n",argv[optind]);
10471 err(
"could not open or read configuration file %s!\n",configName);
10484 QFileInfo configFileInfo(configName);
10501 Doxygen::globalScope =
new NamespaceDef(
"<globalScope>",1,1,
"<globalScope>");
10505 Doxygen::exampleNameDict->setAutoDelete(TRUE);
10507 Doxygen::imageNameDict->setAutoDelete(TRUE);
10515 warn_uncond(
"Output language %s not supported! Using English instead.\n",
10516 outputLanguage.data());
10519 char *s=includePath.first();
10524 s=includePath.next();
10545 char *mapping = extMaps.first();
10548 QCString mapStr = mapping;
10550 if ((i=mapStr.find(
'='))!=-1)
10552 QCString ext=mapStr.left(i).stripWhiteSpace().lower();
10553 QCString language=mapStr.mid(i+1).stripWhiteSpace().lower();
10556 err(
"Failed to map file extension '%s' to unsupported language '%s'.\n"
10557 "Check the EXTENSION_MAPPING setting in the config file.\n",
10558 ext.data(),language.data());
10562 msg(
"Adding custom extension mapping: .%s will be treated as language %s\n",
10563 ext.data(),language.data());
10566 mapping = extMaps.next();
10571 QStrList &expandAsDefinedList =
Config_getList(EXPAND_AS_DEFINED);
10572 s=expandAsDefinedList.first();
10579 s=expandAsDefinedList.next();
10596 msg(
"Cleaning up...\n");
10613 if (generateTagFile.isEmpty())
return;
10615 QFile tag(generateTagFile);
10616 if (!tag.open(IO_WriteOnly))
10618 err(
"cannot open tag file %s for writing\n",
10619 generateTagFile.data()
10624 tagFile <<
"<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>" <<
endl;
10625 tagFile <<
"<tagfile>" <<
endl;
10630 for (fnli.toFirst();(fn=fnli.current());++fnli)
10634 for (fni.toFirst();(fd=fni.current());++fni)
10642 for ( ; (cd=cli.current()) ; ++cli )
10649 for ( ; (nd=nli.current()) ; ++nli )
10656 for (gli.toFirst();(gd=gli.current());++gli)
10663 for (pdi.toFirst();(pd=pdi.current());++pdi)
10667 if (Doxygen::mainPage) Doxygen::mainPage->
writeTagFile(tagFile);
10688 tagFile <<
"</tagfile>" <<
endl;
10696 msg(
"Exiting...\n");
10709 QCString &formatDirName,
10710 const char *defaultDirName)
10713 if (formatDirName.isEmpty())
10715 formatDirName = baseDirName + defaultDirName;
10717 else if (formatDirName[0]!=
'/' && (formatDirName.length()==1 || formatDirName[1]!=
':'))
10719 formatDirName.prepend(baseDirName+
'/');
10721 QDir formatDir(formatDirName);
10722 if (!formatDir.exists() && !formatDir.mkdir(formatDirName))
10724 err(
"Could not create output directory %s\n", formatDirName.data());
10728 return formatDirName;
10734 if (!qchFile.isEmpty())
10742 return QCString(
"../qch/")
10743 + (projectName.isEmpty() ? QCString(
"index") : projectName)
10744 + (versionText.isEmpty() ? QCString(
"") : QCString(
"-") + versionText)
10745 + QCString(
".qch");
10753 excludeNameDict.setAutoDelete(TRUE);
10756 g_s.
begin(
"Searching for include files...\n");
10758 char *s=includePathList.first();
10769 s=includePathList.next();
10773 g_s.
begin(
"Searching for example files...\n");
10775 s=examplePathList.first();
10782 s=examplePathList.next();
10786 g_s.
begin(
"Searching for images...\n");
10788 s=imagePathList.first();
10794 s=imagePathList.next();
10798 g_s.
begin(
"Searching for dot files...\n");
10800 s=dotFileList.first();
10806 s=dotFileList.next();
10810 g_s.
begin(
"Searching for msc files...\n");
10812 s=mscFileList.first();
10818 s=mscFileList.next();
10822 g_s.
begin(
"Searching for dia files...\n");
10824 s=diaFileList.first();
10830 s=diaFileList.next();
10834 g_s.
begin(
"Searching for files to exclude\n");
10836 s=excludeList.first();
10840 0,0,&excludeNameDict,
10843 s=excludeList.next();
10851 g_s.
begin(
"Searching INPUT for files to process...\n");
10852 QDict<void> *killDict =
new QDict<void>(10007);
10855 s=inputList.first();
10859 uint l = path.length();
10863 if (path.at(l-1)==
'\\' || path.at(l-1)==
'/') path=path.left(l-1);
10867 Doxygen::inputNameList,
10868 Doxygen::inputNameDict,
10878 s=inputList.next();
10894 if (outputDirectory.isEmpty())
10896 outputDirectory=QDir::currentDirPath().utf8();
10900 QDir dir(outputDirectory);
10903 dir.setPath(QDir::currentDirPath());
10904 if (!dir.mkdir(outputDirectory))
10906 err(
"tag OUTPUT_DIRECTORY: Output directory `%s' does not "
10907 "exist and cannot be created\n",outputDirectory.data());
10913 msg(
"Notice: Output directory `%s' does not exist. "
10914 "I have created it for you.\n", outputDirectory.data());
10916 dir.cd(outputDirectory);
10918 outputDirectory=dir.absPath().utf8();
10925 Doxygen::symbolStorage =
new Store;
10929 if (cacheSize<0) cacheSize=0;
10930 if (cacheSize>9) cacheSize=9;
10931 uint lookupSize = 65536 << cacheSize;
10957 QCString htmlOutput;
10962 QCString docbookOutput;
10964 if (generateDocbook)
10967 QCString xmlOutput;
10972 QCString latexOutput;
10977 QCString rtfOutput;
10982 QCString manOutput;
10995 if (curFontPath.isEmpty())
10998 QCString newFontPath =
".";
10999 if (!curFontPath.isEmpty())
11002 newFontPath+=curFontPath;
11020 bool defaultLayoutUsed = FALSE;
11021 if (layoutFileName.isEmpty())
11023 layoutFileName =
"DoxygenLayout.xml";
11024 defaultLayoutUsed = TRUE;
11027 QFile layoutFile(layoutFileName);
11028 if (layoutFile.open(IO_ReadOnly))
11030 msg(
"Parsing layout file %s...\n",layoutFileName.data());
11031 QTextStream t(&layoutFile);
11032 t.setEncoding(QTextStream::Latin1);
11035 else if (!defaultLayoutUsed)
11037 warn_uncond(
"failed to open layout file '%s' for reading!\n",layoutFileName.data());
11046 if (generateHtml) exclPatterns.append(htmlOutput);
11047 if (generateDocbook) exclPatterns.append(docbookOutput);
11048 if (generateXml) exclPatterns.append(xmlOutput);
11049 if (generateLatex) exclPatterns.append(latexOutput);
11050 if (generateRtf) exclPatterns.append(rtfOutput);
11051 if (generateMan) exclPatterns.append(manOutput);
11068 if (!g_storage->
open(IO_WriteOnly))
11070 err(
"Failed to create temporary storage file %s\n",
11077 msg(
"Reading and parsing tag files\n");
11080 char *s=tagFileList.first();
11085 s=tagFileList.next();
11099 g_storage->
close();
11108 if (!g_storage->
open(IO_ReadOnly))
11110 err(
"Failed to open temporary storage file %s for reading",
11119 g_s.
begin(
"Building group list...\n");
11124 g_s.
begin(
"Building directory list...\n");
11129 g_s.
begin(
"Building namespace list...\n");
11134 g_s.
begin(
"Building file list...\n");
11139 g_s.
begin(
"Building class list...\n");
11143 g_s.
begin(
"Associating documentation with classes...\n");
11150 g_s.
begin(
"Computing nesting relations for classes...\n");
11163 g_s.
begin(
"Building example list...\n");
11167 g_s.
begin(
"Searching for enumerations...\n");
11175 g_s.
begin(
"Searching for documented typedefs...\n");
11179 g_s.
begin(
"Searching for members imported via using declarations...\n");
11186 g_s.
begin(
"Searching for included using directives...\n");
11190 g_s.
begin(
"Searching for documented variables...\n");
11194 g_s.
begin(
"Building interface member list...\n");
11197 g_s.
begin(
"Building member list...\n");
11201 g_s.
begin(
"Searching for friends...\n");
11205 g_s.
begin(
"Searching for documented defines...\n");
11209 g_s.
begin(
"Computing class inheritance relations...\n");
11214 g_s.
begin(
"Computing class usage relations...\n");
11220 g_s.
begin(
"Searching for tag less structs...\n");
11225 g_s.
begin(
"Flushing cached template relations that have become invalid...\n");
11229 g_s.
begin(
"Computing class relations...\n");
11240 g_s.
begin(
"Add enum values to enums...\n");
11245 g_s.
begin(
"Searching for member function documentation...\n");
11255 g_s.
begin(
"Creating members for template instances...\n");
11259 g_s.
begin(
"Building page list...\n");
11263 g_s.
begin(
"Search for main page...\n");
11268 g_s.
begin(
"Computing page relations...\n");
11273 g_s.
begin(
"Determining the scope of groups...\n");
11278 Doxygen::memberNameSDict->
sort();
11279 Doxygen::functionNameSDict->
sort();
11280 Doxygen::hiddenClasses->
sort();
11281 Doxygen::classSDict->
sort();
11284 msg(
"Freeing entry tree\n");
11286 g_storage->
close();
11293 g_s.
begin(
"Determining which enums are documented\n");
11297 g_s.
begin(
"Computing member relations...\n");
11302 g_s.
begin(
"Building full member lists recursively...\n");
11306 g_s.
begin(
"Adding members to member groups.\n");
11312 g_s.
begin(
"Distributing member group documentation.\n");
11317 g_s.
begin(
"Computing member references...\n");
11323 g_s.
begin(
"Inheriting documentation...\n");
11330 g_s.
begin(
"Generating disk names...\n");
11334 g_s.
begin(
"Adding source references...\n");
11338 g_s.
begin(
"Adding xrefitems...\n");
11343 g_s.
begin(
"Sorting member lists...\n");
11349 g_s.
begin(
"Computing dependencies between directories...\n");
11357 g_s.
begin(
"Generating citations page...\n");
11361 g_s.
begin(
"Counting data structures...\n");
11365 g_s.
begin(
"Resolving user defined references...\n");
11369 g_s.
begin(
"Finding anchors and sections in the documentation...\n");
11373 g_s.
begin(
"Transferring function references...\n");
11377 g_s.
begin(
"Combining using relations...\n");
11381 g_s.
begin(
"Adding members to index pages...\n");
11418 bool generateEclipseHelp =
Config_getBool(GENERATE_ECLIPSEHELP);
11424 if (generateQhp) Doxygen::indexList->
addIndex(
new Qhp);
11425 if (generateTreeView) Doxygen::indexList->
addIndex(
new FTVHelp(TRUE));
11450 err(
"USE_HTAGS is YES but htags(1) failed. \n");
11452 err(
"htags(1) ended normally but failed to load the filemap. \n");
11463 g_s.
begin(
"Generating style sheet...\n");
11469 static bool serverBasedSearch =
Config_getBool(SERVER_BASED_SEARCH);
11471 g_s.
begin(
"Generating search indices...\n");
11480 if (generateHtml && searchEngine)
11483 QDir searchDir(searchDirName);
11484 if (!searchDir.exists() && !searchDir.mkdir(searchDirName))
11486 err(
"Could not create search results directory '%s' $PWD='%s'\n",
11487 searchDirName.data(),QDir::currentDirPath().data());
11491 if (!serverBasedSearch)
11498 g_s.
begin(
"Generating example documentation...\n");
11504 g_s.
begin(
"Generating file sources...\n");
11509 g_s.
begin(
"Generating file documentation...\n");
11513 g_s.
begin(
"Generating page documentation...\n");
11517 g_s.
begin(
"Generating group documentation...\n");
11521 g_s.
begin(
"Generating class documentation...\n");
11525 g_s.
begin(
"Generating namespace index...\n");
11531 g_s.
begin(
"Generating graph info page...\n");
11536 g_s.
begin(
"Generating directory documentation...\n");
11540 if (Doxygen::formulaList->count()>0 && generateHtml
11543 g_s.
begin(
"Generating bitmaps for formulas in HTML...\n");
11550 Doxygen::groupSDict->
sort();
11553 for (gli.toFirst();(gd=gli.current());++gli)
11559 if (g_outputList->
count()>0)
11564 g_s.
begin(
"finalizing index lists...\n");
11568 g_s.
begin(
"writing tag file...\n");
11584 g_s.
begin(
"Generating XML output...\n");
11592 g_s.
begin(
"Generating SQLITE3 output...\n");
11599 g_s.
begin(
"Generating Docbook output...\n");
11606 g_s.
begin(
"Generating AutoGen DEF output...\n");
11612 g_s.
begin(
"Generating Perl module output...\n");
11616 if (generateHtml && searchEngine && serverBasedSearch)
11618 g_s.
begin(
"Generating search index\n");
11628 if (searchDataFile.isEmpty())
11630 searchDataFile=
"searchdata.xml";
11636 Doxygen::searchIndex->
write(searchDataFile);
11645 g_s.
begin(
"Combining RTF output...\n");
11648 err(
"An error occurred during post-processing the RTF files!\n");
11679 if (generateHtml &&
11683 g_s.
begin(
"Running html help compiler...\n");
11684 QString oldDir = QDir::currentDirPath();
11689 err(
"failed to run html help compiler on index.hhp\n");
11692 QDir::setCurrent(oldDir);
11695 if ( generateHtml &&
11699 g_s.
begin(
"Running qhelpgenerator...\n");
11703 QCString
const args = QCString().sprintf(
"%s -o \"%s\"", qhpFileName.data(), qchFileName.data());
11704 QString
const oldDir = QDir::currentDirPath();
11709 err(
"failed to run qhelpgenerator on index.qhp\n");
11712 QDir::setCurrent(oldDir);
11717 msg(
"lookup cache used %d/%d hits=%d misses=%d\n",
11725 msg(
"Note: based on cache misses the ideal setting for LOOKUP_CACHE_SIZE is %d at the cost of higher memory usage.\n",cacheParam);
11730 msg(
"Total elapsed time: %.3f seconds\n(of which %.3f seconds waiting for external tools to finish)\n",
11738 msg(
"finished...\n");
11749 Doxygen::symbolStorage->
close();
11753 QTextCodec::deleteAllCodecs();