summaryrefslogtreecommitdiff
path: root/src/docsets.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/docsets.cpp')
-rw-r--r--src/docsets.cpp522
1 files changed, 522 insertions, 0 deletions
diff --git a/src/docsets.cpp b/src/docsets.cpp
new file mode 100644
index 0000000..e851383
--- /dev/null
+++ b/src/docsets.cpp
@@ -0,0 +1,522 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2012 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <qfile.h>
+#include "docsets.h"
+#include "config.h"
+#include "message.h"
+#include "doxygen.h"
+
+DocSets::DocSets() : m_nodes(17), m_scopes(17)
+{
+ m_nf = 0;
+ m_tf = 0;
+ m_dc = 0;
+ m_id = 0;
+ m_nodes.setAutoDelete(TRUE);
+}
+
+DocSets::~DocSets()
+{
+ delete m_nf;
+ delete m_tf;
+}
+
+void DocSets::initialize()
+{
+ // -- get config options
+ QCString projectName = Config_getString("PROJECT_NAME");
+ if (projectName.isEmpty()) projectName="root";
+ QCString bundleId = Config_getString("DOCSET_BUNDLE_ID");
+ if (bundleId.isEmpty()) bundleId="org.doxygen.Project";
+ QCString feedName = Config_getString("DOCSET_FEEDNAME");
+ if (feedName.isEmpty()) feedName="FeedName";
+ QCString publisherId = Config_getString("DOCSET_PUBLISHER_ID");
+ if (publisherId.isEmpty()) publisherId="PublisherId";
+ QCString publisherName = Config_getString("DOCSET_PUBLISHER_NAME");
+ if (publisherName.isEmpty()) publisherName="PublisherName";
+ QCString projectNumber = Config_getString("PROJECT_NUMBER");
+ if (projectNumber.isEmpty()) projectNumber="ProjectNumber";
+
+ // -- write Makefile
+ {
+ QCString mfName = Config_getString("HTML_OUTPUT") + "/Makefile";
+ QFile makefile(mfName);
+ if (!makefile.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",mfName.data());
+ exit(1);
+ }
+ FTextStream ts(&makefile);
+
+ ts << "DOCSET_NAME=" << bundleId << ".docset\n"
+ "DOCSET_CONTENTS=$(DOCSET_NAME)/Contents\n"
+ "DOCSET_RESOURCES=$(DOCSET_CONTENTS)/Resources\n"
+ "DOCSET_DOCUMENTS=$(DOCSET_RESOURCES)/Documents\n"
+ "DESTDIR=~/Library/Developer/Shared/Documentation/DocSets\n"
+ "XCODE_INSTALL=$(shell xcode-select -print-path)\n"
+ "\n"
+ "all: docset\n"
+ "\n"
+ "docset:\n"
+ "\tmkdir -p $(DOCSET_DOCUMENTS)\n"
+ "\tcp Nodes.xml $(DOCSET_RESOURCES)\n"
+ "\tcp Tokens.xml $(DOCSET_RESOURCES)\n"
+ "\tcp Info.plist $(DOCSET_CONTENTS)\n"
+ "\ttar --exclude $(DOCSET_NAME) \\\n"
+ "\t --exclude Nodes.xml \\\n"
+ "\t --exclude Tokens.xml \\\n"
+ "\t --exclude Info.plist \\\n"
+ "\t --exclude Makefile -c -f - . \\\n"
+ "\t | (cd $(DOCSET_DOCUMENTS); tar xvf -)\n"
+ "\t$(XCODE_INSTALL)/usr/bin/docsetutil index $(DOCSET_NAME)\n"
+ "\trm -f $(DOCSET_DOCUMENTS)/Nodes.xml\n"
+ "\trm -f $(DOCSET_DOCUMENTS)/Info.plist\n"
+ "\trm -f $(DOCSET_DOCUMENTS)/Makefile\n"
+ "\trm -f $(DOCSET_RESOURCES)/Nodes.xml\n"
+ "\trm -f $(DOCSET_RESOURCES)/Tokens.xml\n"
+ "\n"
+ "clean:\n"
+ "\trm -rf $(DOCSET_NAME)\n"
+ "\n"
+ "install: docset\n"
+ "\tmkdir -p $(DESTDIR)\n"
+ "\tcp -R $(DOCSET_NAME) $(DESTDIR)\n"
+ "\n"
+ "uninstall:\n"
+ "\trm -rf $(DESTDIR)/$(DOCSET_NAME)\n"
+ "\n"
+ "always:\n";
+ }
+
+ // -- write Info.plist
+ {
+ QCString plName = Config_getString("HTML_OUTPUT") + "/Info.plist";
+ QFile plist(plName);
+ if (!plist.open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",plName.data());
+ exit(1);
+ }
+ FTextStream ts(&plist);
+
+ ts << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\"\n"
+ "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
+ "<plist version=\"1.0\">\n"
+ "<dict>\n"
+ " <key>CFBundleName</key>\n"
+ " <string>" << projectName << "</string>\n"
+ " <key>CFBundleIdentifier</key>\n"
+ " <string>" << bundleId << "</string>\n"
+ " <key>CFBundleVersion</key>\n"
+ " <string>" << projectNumber << "</string>\n"
+ " <key>DocSetFeedName</key>\n"
+ " <string>" << feedName << "</string>\n"
+ " <key>DocSetPublisherIdentifier</key>\n"
+ " <string>" << publisherId << "</string>\n"
+ " <key>DocSetPublisherName</key>\n"
+ " <string>" << publisherName << "</string>\n"
+ "</dict>\n"
+ "</plist>\n";
+ }
+
+ // -- start Nodes.xml
+ QCString notes = Config_getString("HTML_OUTPUT") + "/Nodes.xml";
+ m_nf = new QFile(notes);
+ if (!m_nf->open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",notes.data());
+ exit(1);
+ }
+ //QCString indexName=Config_getBool("GENERATE_TREEVIEW")?"main":"index";
+ QCString indexName="index";
+ m_nts.setDevice(m_nf);
+ m_nts << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
+ m_nts << "<DocSetNodes version=\"1.0\">" << endl;
+ m_nts << " <TOC>" << endl;
+ m_nts << " <Node>" << endl;
+ m_nts << " <Name>Root</Name>" << endl;
+ m_nts << " <Path>" << indexName << Doxygen::htmlFileExtension << "</Path>" << endl;
+ m_nts << " <Subnodes>" << endl;
+ m_dc = 1;
+ m_firstNode.resize(m_dc);
+ m_firstNode.at(0)=TRUE;
+
+ QCString tokens = Config_getString("HTML_OUTPUT") + "/Tokens.xml";
+ m_tf = new QFile(tokens);
+ if (!m_tf->open(IO_WriteOnly))
+ {
+ err("Could not open file %s for writing\n",tokens.data());
+ exit(1);
+ }
+ m_tts.setDevice(m_tf);
+ m_tts << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
+ m_tts << "<Tokens version=\"1.0\">" << endl;
+}
+
+void DocSets::finalize()
+{
+ if (!m_firstNode.at(m_dc-1))
+ {
+ m_nts << indent() << " </Node>" << endl;
+ }
+ m_dc--;
+ m_nts << " </Subnodes>" << endl;
+ m_nts << " </Node>" << endl;
+ m_nts << " </TOC>" << endl;
+ m_nts << "</DocSetNodes>" << endl;
+ m_nf->close();
+ delete m_nf;
+ m_nf=0;
+
+ m_tts << "</Tokens>" << endl;
+ m_tf->close();
+ delete m_tf;
+ m_tf=0;
+}
+
+QCString DocSets::indent()
+{
+ QCString result;
+ result.fill(' ',(m_dc+2)*2);
+ return result;
+}
+
+void DocSets::incContentsDepth()
+{
+ //printf("DocSets::incContentsDepth() m_dc=%d\n",m_dc);
+ ++m_dc;
+ m_nts << indent() << "<Subnodes>" << endl;
+ m_firstNode.resize(m_dc);
+ if (m_dc>0)
+ {
+ m_firstNode.at(m_dc-1)=TRUE;
+ }
+}
+
+void DocSets::decContentsDepth()
+{
+ if (!m_firstNode.at(m_dc-1))
+ {
+ m_nts << indent() << " </Node>" << endl;
+ }
+ m_nts << indent() << "</Subnodes>" << endl;
+ --m_dc;
+ //printf("DocSets::decContentsDepth() m_dc=%d\n",m_dc);
+}
+
+void DocSets::addContentsItem(bool isDir,
+ const char *name,
+ const char *ref,
+ const char *file,
+ const char *anchor,
+ bool /* separateIndex */,
+ bool /* addToNavIndex */,
+ Definition * /*def*/)
+{
+ (void)isDir;
+ //printf("DocSets::addContentsItem(%s) m_dc=%d\n",name,m_dc);
+ if (ref==0)
+ {
+ if (!m_firstNode.at(m_dc-1))
+ {
+ m_nts << indent() << " </Node>" << endl;
+ }
+ m_firstNode.at(m_dc-1)=FALSE;
+ m_nts << indent() << " <Node>" << endl;
+ m_nts << indent() << " <Name>" << convertToXML(name) << "</Name>" << endl;
+ if (file && file[0]=='^') // URL marker
+ {
+ m_nts << indent() << " <URL>" << convertToXML(&file[1])
+ << "</URL>" << endl;
+ }
+ else // relative file
+ {
+ m_nts << indent() << " <Path>";
+ if (file && file[0]=='!') // user specified file
+ {
+ m_nts << convertToXML(&file[1]);
+ }
+ else if (file) // doxygen generated file
+ {
+ m_nts << file << Doxygen::htmlFileExtension;
+ }
+ m_nts << "</Path>" << endl;
+ if (file && anchor)
+ {
+ m_nts << indent() << " <Anchor>" << anchor << "</Anchor>" << endl;
+ }
+ }
+ }
+}
+
+void DocSets::addIndexItem(Definition *context,MemberDef *md,const char *)
+{
+ if (md==0 && context==0) return;
+
+ FileDef *fd = 0;
+ ClassDef *cd = 0;
+ NamespaceDef *nd = 0;
+
+ if (md)
+ {
+ fd = md->getFileDef();
+ cd = md->getClassDef();
+ nd = md->getNamespaceDef();
+ if (!md->isLinkable()) return; // internal symbol
+ }
+
+ QCString scope;
+ QCString type;
+ QCString decl;
+
+ // determine language
+ QCString lang;
+ SrcLangExt langExt = SrcLangExt_Cpp;
+ if (md)
+ {
+ langExt = md->getLanguage();
+ }
+ else if (context)
+ {
+ langExt = context->getLanguage();
+ }
+ switch (langExt)
+ {
+ case SrcLangExt_Cpp:
+ case SrcLangExt_ObjC:
+ {
+ if (md && (md->isObjCMethod() || md->isObjCProperty()))
+ lang="occ"; // Objective C/C++
+ else if (fd && fd->name().right(2).lower()==".c")
+ lang="c"; // Plain C
+ else if (cd==0 && nd==0)
+ lang="c"; // Plain C symbol outside any class or namespace
+ else
+ lang="cpp"; // C++
+ }
+ break;
+ case SrcLangExt_IDL: lang="idl"; break; // IDL
+ case SrcLangExt_CSharp: lang="csharp"; break; // C#
+ case SrcLangExt_PHP: lang="php"; break; // PHP4/5
+ case SrcLangExt_D: lang="d"; break; // D
+ case SrcLangExt_Java: lang="java"; break; // Java
+ case SrcLangExt_JS: lang="javascript"; break; // Javascript
+ case SrcLangExt_Python: lang="python"; break; // Python
+ case SrcLangExt_Fortran: lang="fortran"; break; // Fortran
+ case SrcLangExt_VHDL: lang="vhdl"; break; // VHDL
+ case SrcLangExt_XML: lang="xml"; break; // DBUS XML
+ case SrcLangExt_Tcl: lang="tcl"; break; // Tcl
+ case SrcLangExt_Markdown:lang="markdown"; break; // Markdown
+ case SrcLangExt_Unknown: lang="unknown"; break; // should not happen!
+ }
+
+ if (md)
+ {
+ if (context==0)
+ {
+ if (md->getGroupDef())
+ context = md->getGroupDef();
+ else if (md->getFileDef())
+ context = md->getFileDef();
+ }
+ if (context==0) return; // should not happen
+
+ switch (md->memberType())
+ {
+ case MemberDef::Define:
+ type="macro"; break;
+ case MemberDef::Function:
+ if (cd && (cd->compoundType()==ClassDef::Interface ||
+ cd->compoundType()==ClassDef::Class))
+ {
+ if (md->isStatic())
+ type="clm"; // class member
+ else
+ type="instm"; // instance member
+ }
+ else if (cd && cd->compoundType()==ClassDef::Protocol)
+ {
+ if (md->isStatic())
+ type="intfcm"; // interface class member
+ else
+ type="intfm"; // interface member
+ }
+ else
+ type="func";
+ break;
+ case MemberDef::Variable:
+ type="data"; break;
+ case MemberDef::Typedef:
+ type="tdef"; break;
+ case MemberDef::Enumeration:
+ type="enum"; break;
+ case MemberDef::EnumValue:
+ type="econst"; break;
+ //case MemberDef::Prototype:
+ // type="prototype"; break;
+ case MemberDef::Signal:
+ type="signal"; break;
+ case MemberDef::Slot:
+ type="slot"; break;
+ case MemberDef::Friend:
+ type="ffunc"; break;
+ case MemberDef::DCOP:
+ type="dcop"; break;
+ case MemberDef::Property:
+ if (cd && cd->compoundType()==ClassDef::Protocol)
+ type="intfp"; // interface property
+ else
+ type="instp"; // instance property
+ break;
+ case MemberDef::Event:
+ type="event"; break;
+ }
+ cd = md->getClassDef();
+ nd = md->getNamespaceDef();
+ if (cd)
+ {
+ scope = cd->qualifiedName();
+ }
+ else if (nd)
+ {
+ scope = nd->name();
+ }
+ MemberDef *declMd = md->memberDeclaration();
+ if (declMd==0) declMd = md;
+ {
+ fd = md->getFileDef();
+ if (fd)
+ {
+ decl = fd->name();
+ }
+ }
+ writeToken(m_tts,md,type,lang,scope,md->anchor(),decl);
+ }
+ else if (context && context->isLinkable())
+ {
+ if (fd==0 && context->definitionType()==Definition::TypeFile)
+ {
+ fd = (FileDef*)context;
+ }
+ if (cd==0 && context->definitionType()==Definition::TypeClass)
+ {
+ cd = (ClassDef*)context;
+ }
+ if (nd==0 && context->definitionType()==Definition::TypeNamespace)
+ {
+ nd = (NamespaceDef*)context;
+ }
+ if (fd)
+ {
+ type="file";
+ }
+ else if (cd)
+ {
+ scope = cd->qualifiedName();
+ if (cd->isTemplate())
+ {
+ type="tmplt";
+ }
+ else if (cd->compoundType()==ClassDef::Protocol)
+ {
+ type="intf";
+ if (scope.right(2)=="-p") scope=scope.left(scope.length()-2);
+ }
+ else if (cd->compoundType()==ClassDef::Interface)
+ {
+ type="cl";
+ }
+ else if (cd->compoundType()==ClassDef::Category)
+ {
+ type="cat";
+ }
+ else
+ {
+ type = "cl";
+ }
+ IncludeInfo *ii = cd->includeInfo();
+ if (ii)
+ {
+ decl=ii->includeName;
+ if (decl.isEmpty())
+ {
+ decl=ii->local;
+ }
+ }
+ }
+ else if (nd)
+ {
+ scope = nd->name();
+ type = "ns";
+ }
+ if (m_scopes.find(context->getOutputFileBase())==0)
+ {
+ writeToken(m_tts,context,type,lang,scope,0,decl);
+ m_scopes.append(context->getOutputFileBase(),(void*)0x8);
+ }
+ }
+}
+
+void DocSets::writeToken(FTextStream &t,
+ const Definition *d,
+ const QCString &type,
+ const QCString &lang,
+ const char *scope,
+ const char *anchor,
+ const char *decl)
+{
+ t << " <Token>" << endl;
+ t << " <TokenIdentifier>" << endl;
+ QCString name = d->name();
+ if (name.right(2)=="-p") name=name.left(name.length()-2);
+ t << " <Name>" << convertToXML(name) << "</Name>" << endl;
+ if (!lang.isEmpty())
+ {
+ t << " <APILanguage>" << lang << "</APILanguage>" << endl;
+ }
+ if (!type.isEmpty())
+ {
+ t << " <Type>" << type << "</Type>" << endl;
+ }
+ if (scope)
+ {
+ t << " <Scope>" << convertToXML(scope) << "</Scope>" << endl;
+ }
+ t << " </TokenIdentifier>" << endl;
+ t << " <Path>" << d->getOutputFileBase()
+ << Doxygen::htmlFileExtension << "</Path>" << endl;
+ if (anchor)
+ {
+ t << " <Anchor>" << anchor << "</Anchor>" << endl;
+ }
+ QCString tooltip = d->briefDescriptionAsTooltip();
+ if (!tooltip.isEmpty())
+ {
+ t << " <Abstract>" << convertToXML(tooltip) << "</Abstract>" << endl;
+ }
+ if (decl)
+ {
+ t << " <DeclaredIn>" << convertToXML(decl) << "</DeclaredIn>" << endl;
+ }
+ t << " </Token>" << endl;
+}
+
+void DocSets::addIndexFile(const char *name)
+{
+ (void)name;
+}
+