1 /**************************************************************************//**
2 * \file ExtractDocs.cpp
3 * \author Gary Harris
4 * \date 01-02-2010
5 *
6 * DoxyBlocks - doxygen integration for Code::Blocks. \n
7 * Copyright (C) 2010 Gary Harris.
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 *----------------------------------------------------------------------------------------------- \n
23 * The initial inspiration and framework for DoxyBlocks were derived
24 * from:
25 *
26 * doxygen_docs.script by jomeggs. \n
27 * Script for automated doxygen documentation. \n
28 * Released under GPL3. \n
29 * (appears to be version 04)
30 *
31 * and this code, which is where DoxyBlocks started, owes it's origins
32 * to that script and jomeggs' lead-up work.
33 *
34 * Many thanks.
35 *****************************************************************************/
36 #include "sdk.h"
37 #ifndef CB_PRECOMP
38 #include <cbproject.h>
39 #include <macrosmanager.h>
40 #include <projectfile.h>
41 #include <projectmanager.h>
42 #endif
43 #include <wx/busyinfo.h>
44 #include <wx/ffile.h>
45 #include <wx/utils.h>
46
47 #include "DoxyBlocks.h"
48
49
OnExtractProject(wxCommandEvent & WXUNUSED (event))50 void DoxyBlocks::OnExtractProject(wxCommandEvent & WXUNUSED(event))
51 {
52 DoExtractProject();
53 }
54
55 /*! \brief Extract and compile documentation for the currently active project.
56 */
DoExtractProject()57 void DoxyBlocks::DoExtractProject()
58 {
59 if(!IsProjectOpen()){
60 return;
61 }
62
63 cbProject* prj = Manager::Get()->GetProjectManager()->GetActiveProject();
64 if(!prj){
65 wxString sMsg = _("Failed to get the active project!");
66 AppendToLog(sMsg, LOG_ERROR);
67 return;
68 }
69
70 // Check whether AutoVersioning is active for this project.
71 if(m_bAutoVersioning){
72 // If we're using autoversion for docs, get the value.
73 if(m_pConfig->GetUseAutoVersion()){
74 m_sAutoVersion = GetAutoVersion();
75 m_pConfig->SetProjectNumber(m_sAutoVersion);
76 // Update the config object and mark the project as modified so the new version gets saved on exit.
77 SaveSettings();
78 prj->SetModified();
79 }
80 }
81
82 AppendToLog(wxT("----------------------------------------------------------------------------------------------------"));
83 AppendToLog(_("Extracting documentation for ") + prj->GetTitle() + wxT("."));
84 AppendToLog(_("DoxyBlocks is working, please wait a few moments..."));
85
86 {
87 wxBusyInfo running(_("Running doxygen. Please wait..."), Manager::Get()->GetAppWindow());
88 GenerateDocuments(prj);
89 } // end lifetime of wxBusyInfo.
90
91 AppendToLog(_("\nDone.\n"));
92 }
93
94 namespace
95 {
96 /*! \brief Converts a boolean value to a string.
97 *
98 * \param val The boolean value to convert.
99 * \return wxString "YES" or "NO".
100 *
101 */
BoolToString(bool val)102 wxString BoolToString(bool val)
103 {
104 return (val ? wxT("YES") : wxT("NO"));
105 }
106 }
107
108
109 /*! \brief Write the doxygen configuration and log files.
110 *
111 * \param prj cbProject* The project.
112 * \param sPrjName wxString The project's name.
113 * \param sPrjPath wxString The path to the project.
114 * \param sDoxygenDir wxString The relative path to the doxygen files.
115 * \param fnDoxyfile wxFileName Doxyfile filename object.
116 * \param fnDoxygenLog wxFileName Doxygen log filename object.
117 *
118 */
WriteConfigFiles(cbProject * prj,wxString sPrjName,wxString,wxString,wxFileName fnDoxyfile,wxFileName fnDoxygenLog)119 void DoxyBlocks::WriteConfigFiles(cbProject *prj, wxString sPrjName, wxString /*sPrjPath*/, wxString /*sDoxygenDir*/, wxFileName fnDoxyfile, wxFileName fnDoxygenLog)
120 {
121 wxArrayString sOutput;
122 wxArrayString sErrors;
123 MacrosManager *pMacMngr = Manager::Get()->GetMacrosManager();
124
125 // If there is no config file, create one. If it exists, check prefs.
126 bool bWrite = true;
127 if(wxFile::Exists(fnDoxyfile.GetFullPath())){
128 bWrite = false;
129 AppendToLog(_("Found existing doxyfile..."));
130 bool bOverwriteDoxyfile = m_pConfig->GetOverwriteDoxyfile();
131 if(bOverwriteDoxyfile){
132 bool bPromptB4Overwriting = m_pConfig->GetPromptBeforeOverwriting();
133 if(bPromptB4Overwriting){
134 if(wxMessageBox(_("Overwrite existing doxyfile?"), wxT("DoxyBlocks"), wxYES_NO|wxCENTRE) == wxYES){
135 bWrite = true;
136 }
137 }
138 else{
139 bWrite = true;
140 }
141 }
142 }
143
144 if(bWrite){
145 AppendToLog(_("Writing doxyfile..."));
146 // Keep the CHM separate for easy access.
147 wxString sChmFile = wxT("../") + sPrjName + wxT(".chm");
148 // Get the list of files from which to extract documentation.
149 wxString sInputList = GetInputList(prj, fnDoxyfile);
150
151 // Project.
152 wxString sPrjNum = m_pConfig->GetProjectNumber();
153 wxString sLanguage = m_pConfig->GetOutputLanguage();
154 // Build.
155 wxString sExtractAll = BoolToString(m_pConfig->GetExtractAll());
156 wxString sExtractPrivate = BoolToString(m_pConfig->GetExtractPrivate());
157 wxString sExtractStatic = BoolToString(m_pConfig->GetExtractStatic());
158 // Warnings.
159 wxString sWarnings = BoolToString(m_pConfig->GetWarnings());
160 wxString sWarnIfUndoc = BoolToString(m_pConfig->GetWarnIfUndocumented());
161 wxString sWarnIfDocError = BoolToString(m_pConfig->GetWarnIfDocError());
162 wxString sWarnNoParamDoc = BoolToString(m_pConfig->GetWarnNoParamdoc());
163 // Alphabetical Class Index.
164 wxString sAlphaIndex = BoolToString(m_pConfig->GetAlphabeticalIndex());
165 // Output.
166 wxString sGenerateHTML = BoolToString(m_pConfig->GetGenerateHTML());
167 wxString sGenerateHTMLHelp = BoolToString(m_pConfig->GetGenerateHTMLHelp());
168 wxString sPathHHC = pMacMngr->ReplaceMacros(m_pConfig->GetPathHHC());
169 wxString sGenerateCHI = BoolToString(m_pConfig->GetGenerateCHI());
170 wxString sBinaryTOC = BoolToString(m_pConfig->GetBinaryTOC());
171 wxString sGenerateLatex = BoolToString(m_pConfig->GetGenerateLatex());
172 wxString sGenerateRTF = BoolToString(m_pConfig->GetGenerateRTF());
173 wxString sGenerateMan = BoolToString(m_pConfig->GetGenerateMan());
174 wxString sGenerateXML = BoolToString(m_pConfig->GetGenerateXML());
175 wxString sGenerateAutogenDef = BoolToString(m_pConfig->GetGenerateAutogenDef());
176 wxString sGeneratePerlMod = BoolToString(m_pConfig->GetGeneratePerlMod());
177 // Pre-processor.
178 wxString sEnablePreproc = BoolToString(m_pConfig->GetEnablePreprocessing());
179 // Dot.
180 wxString sClassDiag = BoolToString(m_pConfig->GetClassDiagrams());
181 wxString sHaveDot = BoolToString(m_pConfig->GetHaveDot());
182 wxString sPathDot = pMacMngr->ReplaceMacros(m_pConfig->GetPathDot());
183
184 // Create a full doxygen 1.7.3 config file without comments.
185 wxString sText;
186 wxString nl = wxT("\n");
187 wxString qnl = wxT("\"\n");
188 sText = wxT("#******************************************************************************\n");
189 sText += wxString(wxT("# ")) + _("Base configuration for doxygen, generated by DoxyBlocks") + wxT(".\n");
190 sText += wxString(wxT("# ")) + _("You may change these defaults to suit your purposes") + wxT(".\n");
191 sText += wxT("#******************************************************************************\n\n");
192
193 sText += wxT("# Doxyfile 1.7.3\n");
194 sText += wxT("\n");
195 sText += wxT("#---------------------------------------------------------------------------\n");
196 sText += wxT("# Project related configuration options\n");
197 sText += wxT("#---------------------------------------------------------------------------\n");
198 sText += wxT("DOXYFILE_ENCODING = UTF-8\n");
199 sText += wxT("PROJECT_NAME = ") + sPrjName + nl;
200 sText += wxT("PROJECT_NUMBER = ") + sPrjNum + nl;
201 sText += wxT("PROJECT_BRIEF =\n");
202 sText += wxT("PROJECT_LOGO =\n");
203 sText += wxT("OUTPUT_DIRECTORY =\n");
204 sText += wxT("CREATE_SUBDIRS = NO\n");
205 sText += wxT("OUTPUT_LANGUAGE = ") + sLanguage + nl;
206 sText += wxT("BRIEF_MEMBER_DESC = YES\n");
207 sText += wxT("REPEAT_BRIEF = YES\n");
208 sText += wxT("ABBREVIATE_BRIEF =\n");
209 sText += wxT("ALWAYS_DETAILED_SEC = NO\n");
210 sText += wxT("INLINE_INHERITED_MEMB = NO\n");
211 sText += wxT("FULL_PATH_NAMES = NO\n");
212 sText += wxT("STRIP_FROM_PATH =\n");
213 sText += wxT("STRIP_FROM_INC_PATH =\n");
214 sText += wxT("SHORT_NAMES = NO\n");
215 sText += wxT("JAVADOC_AUTOBRIEF = NO\n");
216 sText += wxT("QT_AUTOBRIEF = NO\n");
217 sText += wxT("MULTILINE_CPP_IS_BRIEF = NO\n");
218 sText += wxT("INHERIT_DOCS = YES\n");
219 sText += wxT("SEPARATE_MEMBER_PAGES = NO\n");
220 sText += wxT("TAB_SIZE = 8\n");
221 sText += wxT("ALIASES =\n");
222 sText += wxT("OPTIMIZE_OUTPUT_FOR_C = NO\n");
223 sText += wxT("OPTIMIZE_OUTPUT_JAVA = NO\n");
224 sText += wxT("OPTIMIZE_FOR_FORTRAN = NO\n");
225 sText += wxT("OPTIMIZE_OUTPUT_VHDL = NO\n");
226 sText += wxT("EXTENSION_MAPPING =\n");
227 sText += wxT("BUILTIN_STL_SUPPORT = NO\n");
228 sText += wxT("CPP_CLI_SUPPORT = NO\n");
229 sText += wxT("SIP_SUPPORT = NO\n");
230 sText += wxT("IDL_PROPERTY_SUPPORT = YES\n");
231 sText += wxT("DISTRIBUTE_GROUP_DOC = NO\n");
232 sText += wxT("SUBGROUPING = YES\n");
233 sText += wxT("TYPEDEF_HIDES_STRUCT = NO\n");
234 sText += wxT("SYMBOL_CACHE_SIZE = 0\n");
235
236 sText += wxT("#---------------------------------------------------------------------------\n");
237 sText += wxT("# Build related configuration options\n");
238 sText += wxT("#---------------------------------------------------------------------------\n");
239 sText += wxT("EXTRACT_ALL = ") + sExtractAll + nl;
240 sText += wxT("EXTRACT_PRIVATE = ") + sExtractPrivate + nl;
241 sText += wxT("EXTRACT_STATIC = ") + sExtractStatic + nl;
242 sText += wxT("EXTRACT_LOCAL_CLASSES = YES\n");
243 sText += wxT("EXTRACT_LOCAL_METHODS = NO\n");
244 sText += wxT("EXTRACT_ANON_NSPACES = NO\n");
245 sText += wxT("HIDE_UNDOC_MEMBERS = NO\n");
246 sText += wxT("HIDE_UNDOC_CLASSES = NO\n");
247 sText += wxT("HIDE_FRIEND_COMPOUNDS = NO\n");
248 sText += wxT("HIDE_IN_BODY_DOCS = NO\n");
249 sText += wxT("INTERNAL_DOCS = NO\n");
250 sText += wxT("CASE_SENSE_NAMES = NO\n");
251 sText += wxT("HIDE_SCOPE_NAMES = NO\n");
252 sText += wxT("SHOW_INCLUDE_FILES = YES\n");
253 sText += wxT("FORCE_LOCAL_INCLUDES = NO\n");
254 sText += wxT("INLINE_INFO = YES\n");
255 sText += wxT("SORT_MEMBER_DOCS = YES\n");
256 sText += wxT("SORT_BRIEF_DOCS = NO\n");
257 sText += wxT("SORT_MEMBERS_CTORS_1ST = NO\n");
258 sText += wxT("SORT_GROUP_NAMES = NO\n");
259 sText += wxT("SORT_BY_SCOPE_NAME = NO\n");
260 sText += wxT("STRICT_PROTO_MATCHING = NO\n");
261 sText += wxT("GENERATE_TODOLIST = YES\n");
262 sText += wxT("GENERATE_TESTLIST = YES\n");
263 sText += wxT("GENERATE_BUGLIST = YES\n");
264 sText += wxT("GENERATE_DEPRECATEDLIST= YES\n");
265 sText += wxT("ENABLED_SECTIONS =\n");
266 sText += wxT("MAX_INITIALIZER_LINES = 30\n");
267 sText += wxT("SHOW_USED_FILES = YES\n");
268 sText += wxT("SHOW_DIRECTORIES = NO\n");
269 sText += wxT("SHOW_FILES = YES\n");
270 sText += wxT("SHOW_NAMESPACES = YES\n");
271 sText += wxT("FILE_VERSION_FILTER =\n");
272 sText += wxT("LAYOUT_FILE =\n");
273
274 sText += wxT("#---------------------------------------------------------------------------\n");
275 sText += wxT("# configuration options related to warning and progress messages\n");
276 sText += wxT("#---------------------------------------------------------------------------\n");
277 sText += wxT("QUIET = NO\n");
278 sText += wxT("WARNINGS = ") + sWarnings + nl;
279 sText += wxT("WARN_IF_UNDOCUMENTED = ") + sWarnIfUndoc + nl;
280 sText += wxT("WARN_IF_DOC_ERROR = ") + sWarnIfDocError + nl;
281 sText += wxT("WARN_NO_PARAMDOC = ") + sWarnNoParamDoc + nl;
282 sText += wxT("WARN_FORMAT = \"$file:$line: $text\"\n");
283 sText += wxT("WARN_LOGFILE = \"") + fnDoxygenLog.GetFullPath() + qnl;
284
285 sText += wxT("#---------------------------------------------------------------------------\n");
286 sText += wxT("# configuration options related to the input files\n");
287 sText += wxT("#---------------------------------------------------------------------------\n");
288 sText += sInputList;
289 sText += wxT("INPUT_ENCODING = UTF-8\n");
290 sText += wxT("FILE_PATTERNS =\n");
291 sText += wxT("RECURSIVE = NO\n");
292 sText += wxT("EXCLUDE =\n");
293 sText += wxT("EXCLUDE_SYMLINKS = NO\n");
294 sText += wxT("EXCLUDE_PATTERNS =\n");
295 sText += wxT("EXCLUDE_SYMBOLS =\n");
296 sText += wxT("EXAMPLE_PATH =\n");
297 sText += wxT("EXAMPLE_PATTERNS =\n");
298 sText += wxT("EXAMPLE_RECURSIVE = NO\n");
299 sText += wxT("IMAGE_PATH =\n");
300 sText += wxT("INPUT_FILTER =\n");
301 sText += wxT("FILTER_PATTERNS =\n");
302 sText += wxT("FILTER_SOURCE_FILES = NO\n");
303 sText += wxT("FILTER_SOURCE_PATTERNS =\n");
304
305 sText += wxT("#---------------------------------------------------------------------------\n");
306 sText += wxT("# configuration options related to source browsing\n");
307 sText += wxT("#---------------------------------------------------------------------------\n");
308 sText += wxT("SOURCE_BROWSER = NO\n");
309 sText += wxT("INLINE_SOURCES = NO\n");
310 sText += wxT("STRIP_CODE_COMMENTS = YES\n");
311 sText += wxT("REFERENCED_BY_RELATION = NO\n");
312 sText += wxT("REFERENCES_RELATION = NO\n");
313 sText += wxT("REFERENCES_LINK_SOURCE = YES\n");
314 sText += wxT("USE_HTAGS = NO\n");
315 sText += wxT("VERBATIM_HEADERS = YES\n");
316
317 sText += wxT("#---------------------------------------------------------------------------\n");
318 sText += wxT("# configuration options related to the alphabetical class index\n");
319 sText += wxT("#---------------------------------------------------------------------------\n");
320 sText += wxT("ALPHABETICAL_INDEX = ") + sAlphaIndex + nl;
321 sText += wxT("COLS_IN_ALPHA_INDEX = 5\n");
322 sText += wxT("IGNORE_PREFIX =\n");
323
324 sText += wxT("#---------------------------------------------------------------------------\n");
325 sText += wxT("# configuration options related to the HTML output\n");
326 sText += wxT("#---------------------------------------------------------------------------\n");
327 sText += wxT("GENERATE_HTML = ") + sGenerateHTML + nl;
328 sText += wxT("HTML_OUTPUT = html\n");
329 sText += wxT("HTML_FILE_EXTENSION = .html\n");
330 sText += wxT("HTML_HEADER =\n");
331 sText += wxT("HTML_FOOTER =\n");
332 sText += wxT("HTML_STYLESHEET =\n");
333 sText += wxT("HTML_COLORSTYLE_HUE = 220\n");
334 sText += wxT("HTML_COLORSTYLE_SAT = 100\n");
335 sText += wxT("HTML_COLORSTYLE_GAMMA = 80\n");
336 sText += wxT("HTML_TIMESTAMP = YES\n");
337 sText += wxT("HTML_ALIGN_MEMBERS = YES\n");
338 sText += wxT("HTML_DYNAMIC_SECTIONS = NO\n");
339 sText += wxT("GENERATE_DOCSET = NO\n");
340 sText += wxT("DOCSET_FEEDNAME = \"Doxygen generated docs\"\n");
341 sText += wxT("DOCSET_BUNDLE_ID = org.doxygen.Project\n");
342 sText += wxT("DOCSET_PUBLISHER_ID = org.doxygen.Publisher\n");
343 sText += wxT("DOCSET_PUBLISHER_NAME = Publisher\n");
344 sText += wxT("GENERATE_HTMLHELP = ") + sGenerateHTMLHelp + nl;
345 sText += wxT("CHM_FILE = \"") + sChmFile + qnl;
346 if(!sPathHHC.IsEmpty()){
347 sText += wxT("HHC_LOCATION = \"") + sPathHHC + qnl;
348 }
349 else{
350 sText += wxT("HHC_LOCATION =\n");
351 }
352 sText += wxT("GENERATE_CHI = ") + sGenerateCHI + nl;
353 sText += wxT("CHM_INDEX_ENCODING =\n");
354 sText += wxT("BINARY_TOC = ") + sBinaryTOC + nl;
355 sText += wxT("TOC_EXPAND = NO\n");
356 sText += wxT("GENERATE_QHP = NO\n");
357 sText += wxT("QCH_FILE =\n");
358 sText += wxT("QHP_NAMESPACE = org.doxygen.Project\n");
359 sText += wxT("QHP_VIRTUAL_FOLDER = doc\n");
360 sText += wxT("QHP_CUST_FILTER_NAME =\n");
361 sText += wxT("QHP_CUST_FILTER_ATTRS =\n");
362 sText += wxT("QHP_SECT_FILTER_ATTRS =\n");
363 sText += wxT("QHG_LOCATION =\n");
364 sText += wxT("GENERATE_ECLIPSEHELP = NO\n");
365 sText += wxT("ECLIPSE_DOC_ID = org.doxygen.Project\n");
366 sText += wxT("DISABLE_INDEX = NO\n");
367 sText += wxT("ENUM_VALUES_PER_LINE = 4\n");
368 sText += wxT("GENERATE_TREEVIEW = YES\n");
369 sText += wxT("USE_INLINE_TREES = NO\n");
370 sText += wxT("TREEVIEW_WIDTH = 250\n");
371 sText += wxT("EXT_LINKS_IN_WINDOW = NO\n");
372 sText += wxT("FORMULA_FONTSIZE = 10\n");
373 sText += wxT("FORMULA_TRANSPARENT = YES\n");
374 sText += wxT("USE_MATHJAX = NO\n");
375 sText += wxT("MATHJAX_RELPATH = http://www.mathjax.org/mathjax\n");
376 sText += wxT("SEARCHENGINE = YES\n");
377 sText += wxT("SERVER_BASED_SEARCH = NO\n");
378
379 sText += wxT("#---------------------------------------------------------------------------\n");
380 sText += wxT("# configuration options related to the LaTeX output\n");
381 sText += wxT("#---------------------------------------------------------------------------\n");
382 sText += wxT("GENERATE_LATEX = ") + sGenerateLatex + nl;
383 sText += wxT("LATEX_OUTPUT = latex\n");
384 sText += wxT("LATEX_CMD_NAME = latex\n");
385 sText += wxT("MAKEINDEX_CMD_NAME = makeindex\n");
386 sText += wxT("COMPACT_LATEX = NO\n");
387 sText += wxT("PAPER_TYPE = a4\n");
388 sText += wxT("EXTRA_PACKAGES =\n");
389 sText += wxT("LATEX_HEADER =\n");
390 sText += wxT("PDF_HYPERLINKS = YES\n");
391 sText += wxT("USE_PDFLATEX = YES\n");
392 sText += wxT("LATEX_BATCHMODE = NO\n");
393 sText += wxT("LATEX_HIDE_INDICES = NO\n");
394 sText += wxT("LATEX_SOURCE_CODE = NO\n");
395
396 sText += wxT("#---------------------------------------------------------------------------\n");
397 sText += wxT("# configuration options related to the RTF output\n");
398 sText += wxT("#---------------------------------------------------------------------------\n");
399 sText += wxT("GENERATE_RTF = ") + sGenerateRTF + nl;
400 sText += wxT("RTF_OUTPUT = rtf\n");
401 sText += wxT("COMPACT_RTF = NO\n");
402 sText += wxT("RTF_HYPERLINKS = NO\n");
403 sText += wxT("RTF_STYLESHEET_FILE =\n");
404 sText += wxT("RTF_EXTENSIONS_FILE =\n");
405
406 sText += wxT("#---------------------------------------------------------------------------\n");
407 sText += wxT("# configuration options related to the man page output\n");
408 sText += wxT("#---------------------------------------------------------------------------\n");
409 sText += wxT("GENERATE_MAN = ") + sGenerateMan + nl;
410 sText += wxT("MAN_OUTPUT = man\n");
411 sText += wxT("MAN_EXTENSION = .3\n");
412 sText += wxT("MAN_LINKS = NO\n");
413
414 sText += wxT("#---------------------------------------------------------------------------\n");
415 sText += wxT("# configuration options related to the XML output\n");
416 sText += wxT("#---------------------------------------------------------------------------\n");
417 sText += wxT("GENERATE_XML = ") + sGenerateXML + nl;
418 sText += wxT("XML_OUTPUT = xml\n");
419 sText += wxT("XML_SCHEMA =\n");
420 sText += wxT("XML_DTD =\n");
421 sText += wxT("XML_PROGRAMLISTING = YES\n");
422
423 sText += wxT("#---------------------------------------------------------------------------\n");
424 sText += wxT("# configuration options for the AutoGen Definitions output\n");
425 sText += wxT("#---------------------------------------------------------------------------\n");
426 sText += wxT("GENERATE_AUTOGEN_DEF = ") + sGenerateAutogenDef + nl;
427 sText += wxT("#---------------------------------------------------------------------------\n");
428
429 sText += wxT("# configuration options related to the Perl module output\n");
430 sText += wxT("#---------------------------------------------------------------------------\n");
431 sText += wxT("GENERATE_PERLMOD = ") + sGeneratePerlMod + nl;
432 sText += wxT("PERLMOD_LATEX = NO\n");
433 sText += wxT("PERLMOD_PRETTY = YES\n");
434 sText += wxT("PERLMOD_MAKEVAR_PREFIX =\n");
435 sText += wxT("#---------------------------------------------------------------------------\n");
436
437 sText += wxT("# Configuration options related to the preprocessor\n");
438 sText += wxT("#---------------------------------------------------------------------------\n");
439 sText += wxT("ENABLE_PREPROCESSING = ") + sEnablePreproc + nl;
440 sText += wxT("MACRO_EXPANSION = YES\n");
441 sText += wxT("EXPAND_ONLY_PREDEF = YES\n");
442 sText += wxT("SEARCH_INCLUDES = YES\n");
443 sText += wxT("INCLUDE_PATH =\n");
444 sText += wxT("INCLUDE_FILE_PATTERNS =\n");
445 sText += wxT("PREDEFINED = WXUNUSED()=\n"); /// TODO (Gary#1#): I should look at other macros for inclusion here.
446 sText += wxT("EXPAND_AS_DEFINED =\n");
447 sText += wxT("SKIP_FUNCTION_MACROS = YES\n");
448
449 sText += wxT("#---------------------------------------------------------------------------\n");
450 sText += wxT("# Configuration::additions related to external references\n");
451 sText += wxT("#---------------------------------------------------------------------------\n");
452 sText += wxT("TAGFILES =\n");
453 sText += wxT("GENERATE_TAGFILE =\n");
454 sText += wxT("ALLEXTERNALS = NO\n");
455 sText += wxT("EXTERNAL_GROUPS = YES\n");
456 sText += wxT("PERL_PATH = /usr/bin/perl\n");
457
458 sText += wxT("#---------------------------------------------------------------------------\n");
459 sText += wxT("# Configuration options related to the dot tool\n");
460 sText += wxT("#---------------------------------------------------------------------------\n");
461 sText += wxT("CLASS_DIAGRAMS = ") + sClassDiag + nl;
462 sText += wxT("MSCGEN_PATH =\n");
463 sText += wxT("HIDE_UNDOC_RELATIONS = YES\n");
464 sText += wxT("HAVE_DOT = ") + sHaveDot + nl;
465 sText += wxT("DOT_NUM_THREADS = 0\n");
466 sText += wxT("DOT_FONTNAME = Helvetica\n");
467 sText += wxT("DOT_FONTSIZE = 10\n");
468 sText += wxT("DOT_FONTPATH =\n");
469 sText += wxT("CLASS_GRAPH = YES\n");
470 sText += wxT("COLLABORATION_GRAPH = YES\n");
471 sText += wxT("GROUP_GRAPHS = YES\n");
472 sText += wxT("UML_LOOK = NO\n");
473 sText += wxT("TEMPLATE_RELATIONS = NO\n");
474 sText += wxT("INCLUDE_GRAPH = YES\n");
475 sText += wxT("INCLUDED_BY_GRAPH = YES\n");
476 sText += wxT("CALL_GRAPH = YES\n");
477 sText += wxT("CALLER_GRAPH = NO\n");
478 sText += wxT("GRAPHICAL_HIERARCHY = YES\n");
479 sText += wxT("DIRECTORY_GRAPH = YES\n");
480 sText += wxT("DOT_IMAGE_FORMAT = png\n");
481 if(!sPathDot.IsEmpty()){
482 sText += wxT("DOT_PATH = \"") + sPathDot + qnl;
483 }
484 else{
485 sText += wxT("DOT_PATH =\n");
486 }
487 sText += wxT("DOTFILE_DIRS =\n");
488 sText += wxT("MSCFILE_DIRS =\n");
489 sText += wxT("DOT_GRAPH_MAX_NODES = 50\n");
490 sText += wxT("MAX_DOT_GRAPH_DEPTH = 0\n");
491 sText += wxT("DOT_TRANSPARENT = NO\n");
492 sText += wxT("DOT_MULTI_TARGETS = NO\n");
493 sText += wxT("GENERATE_LEGEND = YES\n");
494 sText += wxT("DOT_CLEANUP = YES\n");
495 sText += wxT("\n");
496
497 wxFFile fileDoxyfile(fnDoxyfile.GetFullPath(), wxT("w"));
498 fileDoxyfile.Write(sText);
499 }
500 }
501
502 /**************************************************************************
503 this is where our work is performed :) (text stolen from Yiannis)
504 **************************************************************************/
505
506 /*! \brief Manage the generation of the doxygen configuration and log files.
507 *
508 * \param prj cbProject* The project.
509 * \return int 0 on success, -1 on failure.
510 * \todo Revisit the path management code and add support for allowing the docs to be created in a different location
511 * to the doxyfile via the OUTPUT_PATH setting e.g. using something like ../docs.
512 */
GenerateDocuments(cbProject * prj)513 int DoxyBlocks::GenerateDocuments(cbProject *prj)
514 {
515
516 // First, I need to change into the project directory. All following actions
517 // will work with relative pathes. This way, stored pathes in doxygen
518 // configuration files won't cause problems after moving to other places.
519 // The current path is to be restored after my actions...
520
521 const wxString sOldPath = wxGetCwd();
522 wxFileName fnProject;
523 fnProject.Assign(prj->GetFilename(), ::wxPATH_NATIVE);
524
525 const wxString sPrjPath = fnProject.GetPath(wxPATH_GET_VOLUME);
526 wxSetWorkingDirectory(sPrjPath);
527
528 // project name, name and path of base config file and logfile
529 const wxString sPrjName = fnProject.GetName();
530 const wxString sOutputDir = m_pConfig->GetOutputDirectory();
531 wxString sDoxygenDir = wxT("doxygen");
532 const wxString sCfgBaseFile = wxT("doxyfile");
533 const wxString sLogFile = wxT("doxygen.log");
534
535 if(!sOutputDir.IsEmpty()){
536 sDoxygenDir = sOutputDir;
537 }
538
539 wxFileName fnOutput(sDoxygenDir, wxT(""));
540 wxFileName fnDoxyfile(sDoxygenDir + wxFileName::GetPathSeparator() + sCfgBaseFile);
541 wxFileName fnDoxygenLog(sDoxygenDir + wxFileName::GetPathSeparator() + sLogFile);
542 fnOutput.Normalize();
543 fnDoxyfile.Normalize();
544 fnDoxygenLog.Normalize();
545
546 if (!fnOutput.Mkdir(0777, wxPATH_MKDIR_FULL)){
547 const wxString sMsg = _("Failed. ") + fnOutput.GetFullPath() + _(" was not created.");
548 AppendToLog(sMsg, LOG_WARNING);
549 wxSetWorkingDirectory(sOldPath);
550 return -1;
551 }
552
553 // I'm in the project directory, now create the doxygen configuration files
554 WriteConfigFiles(prj, sPrjName, sPrjPath, sDoxygenDir, fnDoxyfile, fnDoxygenLog);
555
556 if(!wxFile::Exists(fnDoxyfile.GetFullPath())){
557 const wxString sMsg = _("Failed. ") + fnDoxyfile.GetFullPath() + _(" was not created.");
558 AppendToLog(sMsg, LOG_WARNING);
559 wxSetWorkingDirectory(sOldPath);
560 return -1;
561 }
562 // Drop into the doxygen dir.
563 wxSetWorkingDirectory(sPrjPath + wxFileName::GetPathSeparator() + sDoxygenDir);
564
565 // now tango, launch doxygen...
566 wxArrayString sOutput;
567 wxArrayString sErrors;
568 // Default command.
569 wxString cmd = wxT("doxygen");
570 // If a path is configured, use that instead.
571 wxString sDoxygenPath = Manager::Get()->GetMacrosManager()->ReplaceMacros(m_pConfig->GetPathDoxygen());
572 if(!sDoxygenPath.IsEmpty()){
573 cmd = sDoxygenPath;
574 }
575 wxString doxygenFileFullPath = fnDoxyfile.GetFullPath();
576 QuoteStringIfNeeded(doxygenFileFullPath);
577 const long ret = wxExecute(cmd + wxT(" ") + doxygenFileFullPath, sOutput, sErrors);
578 if(ret != -1){
579 // Write doxygen logfile to the log or remove it if it's empty
580 if(wxFile::Exists(fnDoxygenLog.GetFullPath())){
581 wxString sText;
582 wxFFile fileLog(fnDoxygenLog.GetFullPath());
583 if(fileLog.IsOpened()){
584 fileLog.ReadAll(&sText);
585 fileLog.Close();
586 }
587 else{
588 AppendToLog(_("Failed to open ") + sLogFile, LOG_WARNING);
589 }
590 if(!sText.IsEmpty()){
591 AppendToLog(_("\nContents of doxygen's log file:"));
592 AppendToLog(sText, LOG_WARNING);
593 }
594 else{
595 wxRemoveFile(sLogFile);
596 }
597 }
598
599 // Run docs if HTML was created.
600 if(m_pConfig->GetGenerateHTML()){
601 // Open the newly created HTML docs, if prefs allow.
602 if(m_pConfig->GetRunHTML()){
603 DoRunHTML();
604 }
605 if(m_pConfig->GetGenerateHTMLHelp()){
606 // Open the newly created CHM if prefs allow.
607 if(m_pConfig->GetRunCHM()){
608 RunCompiledHelp(fnDoxyfile.GetPathWithSep() , sPrjName);
609 }
610 }
611 }
612
613 // tell the user where to find the docs
614 const wxString sMsg = wxT("Success.\nYour documents are in: ");
615 AppendToLog(sMsg + fnDoxyfile.GetPathWithSep());
616 }
617 else{
618 // please google, install doxygen, set your path and...
619 AppendToLog(wxString::Format(_("Execution of '%s' failed."), cmd.c_str()), LOG_ERROR);
620 AppendToLog(_("Please ensure that the doxygen 'bin' directory is in your path or provide the specific path in DoxyBlocks' preferences.\n"));
621 }
622
623 // restore to before saved path and bye...
624 wxSetWorkingDirectory(sOldPath);
625 return ret;
626 }
627
628 /*! \brief Get the list of input files for the doxygen configuration file.
629 *
630 * \param prj cbProject* The project.
631 * \param fnDoxyfile wxFileName Doxyfile filename object.
632 * \return wxString The input file list.
633 *
634 * This function queries the cbProject object for a list of files actually attached to the project.
635 * Other files in the project directory are ignored.
636 */
GetInputList(cbProject * prj,wxFileName fnDoxyfile)637 wxString DoxyBlocks::GetInputList(cbProject *prj, wxFileName fnDoxyfile)
638 {
639 // only files with extensions named here will be included in the documentation
640 wxArrayString asExtList;
641 asExtList.Add(wxT("*.c"));
642 asExtList.Add(wxT("*.cc"));
643 asExtList.Add(wxT("*.cxx"));
644 asExtList.Add(wxT("*.cpp"));
645 asExtList.Add(wxT("*.c++"));
646 asExtList.Add(wxT("*.java"));
647 asExtList.Add(wxT("*.ii"));
648 asExtList.Add(wxT("*.ixx"));
649 asExtList.Add(wxT("*.ipp"));
650 asExtList.Add(wxT("*.i++"));
651 asExtList.Add(wxT("*.inl"));
652 asExtList.Add(wxT("*.h"));
653 asExtList.Add(wxT("*.hh"));
654 asExtList.Add(wxT("*.hxx"));
655 asExtList.Add(wxT("*.hpp"));
656 asExtList.Add(wxT("*.h++"));
657 asExtList.Add(wxT("*.idl"));
658 asExtList.Add(wxT("*.odl"));
659 asExtList.Add(wxT("*.cs"));
660 asExtList.Add(wxT("*.php"));
661 asExtList.Add(wxT("*.php3"));
662 asExtList.Add(wxT("*.inc"));
663 asExtList.Add(wxT("*.m"));
664 asExtList.Add(wxT("*.mm"));
665 asExtList.Add(wxT("*.py"));
666 asExtList.Add(wxT("*.f90"));
667
668 // now let's build a string containing all the project files. To be on the safe side,
669 // we will quote them all so spaces and other special chars don't break the actual
670 // command later...
671 wxString sInputList;
672 const int cntExtList = asExtList.GetCount();
673
674 sInputList += wxT("INPUT = ");
675
676 for (FilesList::iterator it = prj->GetFilesList().begin(); it != prj->GetFilesList().end(); ++it)
677 {
678 ProjectFile* prjFile = *it;
679 if(prjFile)
680 {
681 const wxString sFileName = prjFile->relativeFilename;
682 wxFileName fnFileName = prjFile->file;
683 fnFileName.MakeRelativeTo(fnDoxyfile.GetPath());
684 const wxString RelName = fnFileName.GetFullPath();
685
686 /* if the file matches one of the abovementioned filters, add it */
687 for(int n = 0; n < cntExtList; ++n)
688 {
689 if(sFileName.Matches(asExtList.Item(n)))
690 {
691 sInputList += wxT("\\\n\t\"") + RelName + wxT("\" ");
692 break;
693 }
694 }
695 }
696 }
697 sInputList += wxT("\n");
698 return sInputList;
699 }
700