Orb/Doxygen/src/doxygen.cpp
changeset 1 82f11024044a
parent 0 42188c7ea2d9
equal deleted inserted replaced
0:42188c7ea2d9 1:82f11024044a
   152 static QDict<FileDef>   g_usingDeclarations(1009); // used classes
   152 static QDict<FileDef>   g_usingDeclarations(1009); // used classes
   153 static FileStorage     *g_storage = 0;
   153 static FileStorage     *g_storage = 0;
   154 static bool             g_successfulRun = FALSE;
   154 static bool             g_successfulRun = FALSE;
   155 static bool             g_dumpSymbolMap = FALSE;
   155 static bool             g_dumpSymbolMap = FALSE;
   156 static bool             g_dumpConfigAsXML = FALSE;
   156 static bool             g_dumpConfigAsXML = FALSE;
   157 
       
   158 
       
   159 
   157 
   160 void clearAll()
   158 void clearAll()
   161 {
   159 {
   162   g_inputFiles.clear();      
   160   g_inputFiles.clear();      
   163   //g_excludeNameDict.clear();  
   161   //g_excludeNameDict.clear();  
   671             //printf("File %s: in group %s\n",fd->name().data(),s->data());
   669             //printf("File %s: in group %s\n",fd->name().data(),s->data());
   672           }
   670           }
   673         }
   671         }
   674       }
   672       }
   675     }
   673     }
   676     else
   674 	// NOTE: if OUTPUT_INCLUDES is true then we will see files that are not in
       
   675 	// the INPUT list
       
   676     else if (!Config_getBool("OUTPUT_INCLUDES"))
   677     {
   677     {
   678       const char *fn = root->fileName.data();
   678       const char *fn = root->fileName.data();
   679       QCString text;
   679       QCString text;
   680       text.sprintf("Warning: the name `%s' supplied as "
   680       text.sprintf("Warning: the name `%s' supplied as "
   681           "the second argument in the \\file statement ",
   681           "the second argument in the \\file statement ",
  1981   rootNav->changeSection(Entry::EMPTY_SEC);
  1981   rootNav->changeSection(Entry::EMPTY_SEC);
  1982   return md;
  1982   return md;
  1983 }
  1983 }
  1984 
  1984 
  1985 //----------------------------------------------------------------------
  1985 //----------------------------------------------------------------------
       
  1986 /** Recursively dumps the include files.*/
       
  1987 void dumpIncludeGraphRecursive(const FileDef *fd, const QCString &prefix)
       
  1988 {
       
  1989 	if (fd && fd->includeFileList()) {
       
  1990 		QList<IncludeInfo> *incList = fd->includeFileList();
       
  1991 		IncludeInfo *ii;
       
  1992 		for (ii=incList->first(); ii != 0; ii=incList->next()) {
       
  1993 			FileDef *incFd = ii->fileDef;
       
  1994 			if (incFd) {
       
  1995 				Debug::print(Debug::IncludeGraph, 0, "%sInc: %s\n", prefix.data(), incFd->absFilePath().data());
       
  1996 				dumpIncludeGraphRecursive(incFd, "  "+prefix);
       
  1997 			}
       
  1998 		}
       
  1999 	}
       
  2000 }
       
  2001 
       
  2002 /** Dumps the include files.*/
       
  2003 void dumpIncludeGraph()
       
  2004 {
       
  2005 	if (Debug::isFlagSet(Debug::IncludeGraph)) {
       
  2006 		Debug::print(Debug::IncludeGraph, 0, "Include Graph:\n");
       
  2007 		FileNameListIterator incFnli(*Doxygen::inputNameList);
       
  2008 		FileName *incFnLoop;
       
  2009 		for (;(incFnLoop=incFnli.current()); ++incFnli) {
       
  2010 			FileNameIterator incFni(*incFnLoop);
       
  2011 			FileDef *fd;
       
  2012 			for (;(fd=incFni.current()); ++incFni) {
       
  2013 				Debug::print(Debug::IncludeGraph, 0, "File: %s\n", fd->absFilePath().data());
       
  2014 				dumpIncludeGraphRecursive(fd, "  ");
       
  2015 			}
       
  2016 		}
       
  2017 	}
       
  2018 }
       
  2019 
       
  2020 /** Recursively searches the supplied FileDef for an filename that
       
  2021 matches the rootFileName and returns the FileDef* of the include file or
       
  2022 0 on failure.
       
  2023 @param fd The FileDef to search.
       
  2024 @param rootFileName The filename to match on.
       
  2025 */
       
  2026 static FileDef* findIncludeMatch(const FileDef *fd, const QCString &rootFileName)
       
  2027 {
       
  2028 	if (fd && fd->includeFileList()) {
       
  2029 		// Search the include dependency list for a file that matches root->fileName
       
  2030 		QList<IncludeInfo> *incList = fd->includeFileList();
       
  2031 		IncludeInfo *ii;
       
  2032 		for (ii=incList->first(); ii != 0; ii=incList->next()) {
       
  2033 			FileDef *incFd = ii->fileDef;
       
  2034 			// NOTE: this test stops only direct recursion, not indirect recursion
       
  2035 			if (incFd && incFd != fd) {
       
  2036 				if (incFd->absFilePath() == rootFileName) {
       
  2037 					return incFd;
       
  2038 				} else {
       
  2039 					// Depth first search
       
  2040 					FileDef *recurseFd = findIncludeMatch(incFd, rootFileName);
       
  2041 					if (recurseFd) {
       
  2042 						return recurseFd;
       
  2043 					}
       
  2044 				}
       
  2045 			}
       
  2046 		}
       
  2047 	}
       
  2048 	return 0;
       
  2049 }
       
  2050 
       
  2051 /** Adds an include file represented by fd to the list of input files
       
  2052 add it to the Doxygen::inputNameList so that the back ends can see it
       
  2053 as 'forced include'.
       
  2054 @param fd The FileDef that describes the file to include.
       
  2055 */
       
  2056 static void addIncludeFileToInput(FileDef *fd)
       
  2057 {
       
  2058 	FileNameListIterator incFnli(*Doxygen::inputNameList);
       
  2059 	FileName *incFnLoop;
       
  2060 	for (;(incFnLoop=incFnli.current()); ++incFnli) {
       
  2061 		FileNameIterator incFni(*incFnLoop);
       
  2062 		FileDef *listFd;
       
  2063 		for (;(listFd=incFni.current()); ++incFni) {
       
  2064 			// TODO: Test for file name not FileDef address
       
  2065 			if (listFd == fd) {
       
  2066 				// Already have it
       
  2067 				return;
       
  2068 			}
       
  2069 		}
       
  2070 	}
       
  2071 	//printf("Forcing include file onto inputNameList: %s\n", incFd->absFilePath().data());
       
  2072 	//FileName *fn = Doxygen::inputNameList->first();
       
  2073 	FileNameList *fnList = Doxygen::inputNameList;
       
  2074 	FileName *incFn = new FileName(fd->absFilePath(), fd->name());
       
  2075 	incFn->append(fd);
       
  2076 	fnList->inSort(incFn);
       
  2077 	//printf("Forced include file pushed onto inputNameList %p: %s\n", fnList, fd->absFilePath().data());
       
  2078 }
  1986 
  2079 
  1987 static MemberDef *addVariableToFile(
  2080 static MemberDef *addVariableToFile(
  1988     EntryNav *rootNav,
  2081     EntryNav *rootNav,
  1989     MemberDef::MemberType mtype,
  2082     MemberDef::MemberType mtype,
  1990     const QCString &scope,
  2083     const QCString &scope,
  2168 
  2261 
  2169   // add member to the file (we do this even if we have already inserted
  2262   // add member to the file (we do this even if we have already inserted
  2170   // it into the namespace. 
  2263   // it into the namespace. 
  2171   if (fd)
  2264   if (fd)
  2172   {
  2265   {
  2173     md->setFileDef(fd); 
  2266 		//printf("Setting FileDef %s\n", fd->fileName().data());
  2174     fd->insertMember(md);
  2267 		if (root->fileName != fd->absFilePath()) {
       
  2268 			//printf("addVariableToFile() Missmatch Name=\"%s\" Root=%s, FileDef=%s\n",
       
  2269 			//	name.data(),
       
  2270 			//	root->fileName.data(),
       
  2271 			//	fd->absFilePath().data()
       
  2272 			//	);
       
  2273 			// Now search the include dependency list for a file that matches root->fileName
       
  2274 			FileDef *incFd = findIncludeMatch(fd, root->fileName);
       
  2275 			if (incFd) {
       
  2276 				//printf("Found include file match on: %s\n", incFd->absFilePath().data());
       
  2277 				// If found add this FileDef* to the member and add the MemberDef* to the FileDef
       
  2278 				md->setFileDef(incFd);
       
  2279 				incFd->insertMember(md);
       
  2280 				md->setBodyDef(incFd);
       
  2281 				// If this FileDef is not in Doxygen::inputNameList and
       
  2282 				// Config_getBool("OUTPUT_INCLUDES") is true then
       
  2283 				// add it to the Doxygen::inputNameList so that the back ends
       
  2284 				// can see it as 'forced include'.
       
  2285 				if (Config_getBool("OUTPUT_INCLUDES")) {
       
  2286 					addIncludeFileToInput(incFd);
       
  2287 				}
       
  2288 			} else {
       
  2289 				printf("Warning: addVariableToFile() failed to resolve missmatch Name=\"%s\" Root=%s, FileDef=%s\n",
       
  2290 					name.data(),
       
  2291 					root->fileName.data(),
       
  2292 					fd->absFilePath().data()
       
  2293 					);
       
  2294 				//md->setFileDef(fd);
       
  2295 				//fd->insertMember(md);
       
  2296 			}
       
  2297 	  } else {
       
  2298 		//printf("addVariableToFile() Match OK FileDef=%s\n", fd->absFilePath().data());
       
  2299 		md->setFileDef(fd); 
       
  2300 		fd->insertMember(md);
       
  2301 	  }
  2175   }
  2302   }
  2176 
  2303 
  2177   // add member definition to the list of globals 
  2304   // add member definition to the list of globals 
  2178   if (mn)
  2305   if (mn)
  2179   {
  2306   {
  2181   }
  2308   }
  2182   else
  2309   else
  2183   {
  2310   {
  2184     mn = new MemberName(name);
  2311     mn = new MemberName(name);
  2185     mn->append(md);
  2312     mn->append(md);
       
  2313 	// PaulRoss: This first line looks wrong to me but links to typedef's don't work without it!
  2186     Doxygen::functionNameSDict->append(name,mn);
  2314     Doxygen::functionNameSDict->append(name,mn);
       
  2315     //Doxygen::memberNameSDict->append(name,mn);
  2187   }
  2316   }
  2188   rootNav->changeSection(Entry::EMPTY_SEC);
  2317   rootNav->changeSection(Entry::EMPTY_SEC);
  2189   return md;
  2318   return md;
  2190 }
  2319 }
  2191 
  2320 
  2352                    root->name.data(),
  2481                    root->name.data(),
  2353                    root->args.data(),
  2482                    root->args.data(),
  2354                    root->bodyLine,
  2483                    root->bodyLine,
  2355                    root->mGrpId
  2484                    root->mGrpId
  2356                 );
  2485                 );
  2357     //printf("root->parent->name=%s\n",root->parent->name.data());
  2486 	//Entry *pParent = root->parent();
  2358 
  2487 	//if (pParent) {
       
  2488 	//	printf("root->parent->name=%s\n",root->parent()->name.data());
       
  2489 	//} else {
       
  2490 	//	printf("NO Parent\n");
       
  2491 	//}
  2359     if (root->type.isEmpty() && root->name.find("operator")==-1 &&
  2492     if (root->type.isEmpty() && root->name.find("operator")==-1 &&
  2360         (root->name.find('*')!=-1 || root->name.find('&')!=-1))
  2493         (root->name.find('*')!=-1 || root->name.find('&')!=-1))
  2361     {
  2494     {
  2362       // recover from parse error caused by redundant braces 
  2495       // recover from parse error caused by redundant braces 
  2363       // like in "int *(var[10]);", which is parsed as
  2496       // like in "int *(var[10]);", which is parsed as
  2556       rootNav->section()==Entry::VARIABLE_SEC &&
  2689       rootNav->section()==Entry::VARIABLE_SEC &&
  2557       rootNav->type().find("typedef ")!=-1 // its a typedef
  2690       rootNav->type().find("typedef ")!=-1 // its a typedef
  2558      ) 
  2691      ) 
  2559   {
  2692   {
  2560     addVariable(rootNav);
  2693     addVariable(rootNav);
       
  2694 	//printf("addVariable() done\n");
  2561   }
  2695   }
  2562   if (rootNav->children())
  2696   if (rootNav->children())
  2563   {
  2697   {
  2564     EntryNavListIterator eli(*rootNav->children());
  2698     EntryNavListIterator eli(*rootNav->children());
  2565     EntryNav *e;
  2699     EntryNav *e;
  2643   // strip redundant template specifier for constructors
  2777   // strip redundant template specifier for constructors
  2644   if ((fd==0 || getLanguageFromFileName(fd->name())==SrcLangExt_Cpp) &&
  2778   if ((fd==0 || getLanguageFromFileName(fd->name())==SrcLangExt_Cpp) &&
  2645      name.left(9)!="operator " && (i=name.find('<'))!=-1 && name.find('>')!=-1)
  2779      name.left(9)!="operator " && (i=name.find('<'))!=-1 && name.find('>')!=-1)
  2646   {
  2780   {
  2647     name=name.left(i); 
  2781     name=name.left(i); 
       
  2782   }
       
  2783   if (Config_getBool("PREPROCESS_INCLUDES")) {
       
  2784     // If we are preprocessing the #included files we might have seen
       
  2785     // this member  more than once so we
       
  2786     // only add a member where one did not exist before
       
  2787 	  QCString myDefName = name;
       
  2788 	  myDefName.append(root->args);
       
  2789 	  if(cd->hasFunction(myDefName, root->protection)) {
       
  2790 	  //if (Doxygen::memberNameSDict->find(name)) {
       
  2791 		//printf("addMethodToClass() rejecting: %p %d %s::%s\n", cd, root->protection, cd->name().data(), myDefName.data());
       
  2792 		return;
       
  2793 	}
       
  2794 	//printf("addMethodToClass() accepting: %p %d %s::%s\n", cd, root->protection, cd->name().data(), myDefName.data());
  2648   }
  2795   }
  2649 
  2796 
  2650   //printf("root->name=`%s; root->args=`%s' root->argList=`%s'\n", 
  2797   //printf("root->name=`%s; root->args=`%s' root->argList=`%s'\n", 
  2651   //    root->name.data(),root->args.data(),argListToString(root->argList).data()
  2798   //    root->name.data(),root->args.data(),argListToString(root->argList).data()
  2652   //   );
  2799   //   );
  8482       htmlStyleSheet.resize(0); // revert to the default
  8629       htmlStyleSheet.resize(0); // revert to the default
  8483     }
  8630     }
  8484   }
  8631   }
  8485 }
  8632 }
  8486 
  8633 
       
  8634 static void reportParseFileSize(const QCString *fileName, const BufStr &theBuf)
       
  8635 {
       
  8636 	int numLines = 1;
       
  8637 	int numWs = 0;
       
  8638 	int byteCount = 0;
       
  8639 	for (int i=0; i < theBuf.size(); ++i) {
       
  8640 		if ('\n' == theBuf.at(i)) {
       
  8641 			++numLines;
       
  8642 		} else if (' ' == theBuf.at(i)) {
       
  8643 			++numWs;
       
  8644 		}
       
  8645 		++byteCount;
       
  8646 		//if ('\0' == theBuf.at(i)) {
       
  8647 		//	break;
       
  8648 		//}
       
  8649 	}
       
  8650 	msg("Have input for \"%s\", bytes=%d, buffer size=%d bytes, lines=%d ws=%d\n",
       
  8651 		fileName->data(),
       
  8652 		byteCount,
       
  8653 		theBuf.size(),
       
  8654 		numLines,
       
  8655 		numWs);
       
  8656 }
  8487 
  8657 
  8488 //! parse the list of input files
  8658 //! parse the list of input files
  8489 static void parseFiles(Entry *root,EntryNav *rootNav)
  8659 static void parseFiles(Entry *root,EntryNav *rootNav)
  8490 {
  8660 {
  8491 #if 0
  8661 #if 0
  8525     else // no preprocessing
  8695     else // no preprocessing
  8526     {
  8696     {
  8527       msg("Reading %s...\n",s->data());
  8697       msg("Reading %s...\n",s->data());
  8528       readInputFile(fileName,preBuf);
  8698       readInputFile(fileName,preBuf);
  8529     }
  8699     }
  8530 	msg("Have input for \"%s\", size=%d bytes.\n", s->data(), preBuf.size());
  8700 	reportParseFileSize(s, preBuf);
  8531     BufStr convBuf(preBuf.curPos()+1024);
  8701     BufStr convBuf(preBuf.curPos()+1024);
  8532 
  8702 
  8533     // convert multi-line C++ comments to C style comments
  8703     // convert multi-line C++ comments to C style comments
  8534     convertCppComments(&preBuf,&convBuf,fileName);
  8704     convertCppComments(&preBuf,&convBuf,fileName);
  8535 
  8705 
 10103   
 10273   
 10104   msg("Determining which enums are documented\n");
 10274   msg("Determining which enums are documented\n");
 10105   findDocumentedEnumValues();
 10275   findDocumentedEnumValues();
 10106 
 10276 
 10107   msg("Computing member relations...\n");
 10277   msg("Computing member relations...\n");
       
 10278   // TODO: This seems to generate an infinite loop
 10108   computeMemberRelations();
 10279   computeMemberRelations();
 10109 
 10280 
 10110   msg("Building full member lists recursively...\n");
 10281   msg("Building full member lists recursively...\n");
 10111   buildCompleteMemberLists();
 10282   buildCompleteMemberLists();
 10112   
 10283   
 10160   msg("Combining using relations...\n");
 10331   msg("Combining using relations...\n");
 10161   combineUsingRelations();
 10332   combineUsingRelations();
 10162 
 10333 
 10163   msg("Adding members to index pages...\n");
 10334   msg("Adding members to index pages...\n");
 10164   addMembersToIndex();
 10335   addMembersToIndex();
       
 10336   dumpIncludeGraph();
 10165 }
 10337 }
 10166 
 10338 
 10167 void generateOutput()
 10339 void generateOutput()
 10168 {
 10340 {
 10169   /**************************************************************************
 10341   /**************************************************************************