summaryrefslogtreecommitdiffstats
path: root/addon/doxmlparser/examples
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2021-02-02 20:21:27 (GMT)
committerDimitri van Heesch <doxygen@gmail.com>2021-02-02 20:34:58 (GMT)
commit095c5de5e4df192898f7f13e9b51524999615983 (patch)
tree2d04e5aacb490898ed8053100cc1eca334f6be4a /addon/doxmlparser/examples
parentcd3c39c11084a326baee2e81420fe13a5dacb8e2 (diff)
downloadDoxygen-095c5de5e4df192898f7f13e9b51524999615983.zip
Doxygen-095c5de5e4df192898f7f13e9b51524999615983.tar.gz
Doxygen-095c5de5e4df192898f7f13e9b51524999615983.tar.bz2
Replace the C++ doxmlparser libary by a python based module
Diffstat (limited to 'addon/doxmlparser/examples')
-rw-r--r--addon/doxmlparser/examples/CMakeLists.txt2
-rw-r--r--addon/doxmlparser/examples/dump/dump.py31
-rw-r--r--addon/doxmlparser/examples/metrics/CMakeLists.txt18
-rw-r--r--addon/doxmlparser/examples/metrics/main.cpp271
-rw-r--r--addon/doxmlparser/examples/metrics/metrics.py225
5 files changed, 256 insertions, 291 deletions
diff --git a/addon/doxmlparser/examples/CMakeLists.txt b/addon/doxmlparser/examples/CMakeLists.txt
deleted file mode 100644
index 1e08d36..0000000
--- a/addon/doxmlparser/examples/CMakeLists.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-
-add_subdirectory(metrics)
diff --git a/addon/doxmlparser/examples/dump/dump.py b/addon/doxmlparser/examples/dump/dump.py
new file mode 100644
index 0000000..240c14a
--- /dev/null
+++ b/addon/doxmlparser/examples/dump/dump.py
@@ -0,0 +1,31 @@
+# An minimal example showing how to use the python doxmlparser module to read
+# the XML output generated by doxygen for a project and dump it to the output again.
+
+import sys
+
+import doxmlparser
+
+# process a compound file and export the results to stdout
+def parse_compound(inDirName,baseName):
+ doxmlparser.compound.parse(inDirName+"/"+baseName+".xml",False)
+
+# process the index file and export the results to stdout
+def parse_index(inDirName):
+ rootObj = doxmlparser.index.parse(inDirName+"/index.xml",False)
+ for compound in rootObj.get_compound(): # for each compound defined in the index
+ parse_compound(inDirName,compound.get_refid())
+
+def usage():
+ print("Usage {0} <xml_output_dir>".format(sys.argv[0]))
+ sys.exit(1)
+
+def main():
+ args = sys.argv[1:]
+ if len(args)==1:
+ parse_index(args[0])
+ else:
+ usage()
+
+if __name__ == '__main__':
+ main()
+
diff --git a/addon/doxmlparser/examples/metrics/CMakeLists.txt b/addon/doxmlparser/examples/metrics/CMakeLists.txt
deleted file mode 100644
index 7e99a08..0000000
--- a/addon/doxmlparser/examples/metrics/CMakeLists.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-
-include_directories(
- ../../include
- ${PROJECT_SOURCE_DIR}/libversion
-)
-
-add_executable(doxmlparser_metrics
-main.cpp
-)
-
-
-target_link_libraries(doxmlparser_metrics
- doxmlparser
- doxygen_version
- qtools
- ${COVERAGE_LINKER_FLAGS}
-)
-
diff --git a/addon/doxmlparser/examples/metrics/main.cpp b/addon/doxmlparser/examples/metrics/main.cpp
deleted file mode 100644
index 9e301b1..0000000
--- a/addon/doxmlparser/examples/metrics/main.cpp
+++ /dev/null
@@ -1,271 +0,0 @@
-/******************************************************************************
- *
- * $Id$
- *
- *
- * Copyright (C) 1997-2006 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.
- *
- */
-
-/*! \mainpage Metrics
- * This is a small example that shows how to use doxygen's XML output and
- * the doxmlparser library. The example shows some very basic code metrics.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <doxmlintf.h>
-#include "version.h"
-
-bool isDocumented(IDocRoot *brief,IDocRoot *detailed)
-{
- bool found=false;
- if (brief)
- {
- IDocIterator *docIt = brief->contents();
- if (docIt->current()) // method has brief description
- {
- found=true;
- }
- docIt->release();
- }
- if (detailed && !found)
- {
- IDocIterator *docIt = detailed->contents();
- if (docIt->current())
- {
- found=true;
- }
- docIt->release();
- }
- return found;
-}
-
-int main(int argc,char **argv)
-{
- int locArgc = argc;
-
- if (locArgc == 2)
- {
- if (!strcmp(argv[1],"--help"))
- {
- printf("Usage: %s xml_dir\n",argv[0]);
- exit(0);
- }
- else if (!strcmp(argv[1],"--version"))
- {
- printf("%s version: %s\n",argv[0],getFullVersion());
- exit(0);
- }
- }
-
- if (locArgc!=2)
- {
- printf("Usage: %s xml_dir\n",argv[0]);
- exit(1);
- }
-
- int numClasses=0;
- int numDocClasses=0;
- int numStructs=0;
- int numUnions=0;
- int numInterfaces=0;
- int numExceptions=0;
- int numNamespaces=0;
- int numFiles=0;
- int numGroups=0;
- int numPages=0;
- int numPackages=0;
- int numPubMethods=0;
- int numProMethods=0;
- int numPriMethods=0;
- int numDocPubMethods=0;
- int numDocProMethods=0;
- int numDocPriMethods=0;
- int numFunctions=0;
- int numAttributes=0;
- int numVariables=0;
- int numDocFunctions=0;
- int numDocAttributes=0;
- int numDocVariables=0;
- int numParams=0;
-
- IDoxygen *dox = createObjectModel();
-
- dox->setDebugLevel(0);
-
- if (!dox->readXMLDir(argv[1]))
- {
- printf("Error reading %s/index.xml\n",argv[1]);
- exit(1);
- }
-
- ICompoundIterator *cli = dox->compounds();
- ICompound *comp;
- for (cli->toFirst();(comp=cli->current());cli->toNext())
- {
- printf("Processing %s...\n",comp->name()->latin1());
- bool hasDocs = isDocumented(comp->briefDescription(),comp->detailedDescription());
- switch (comp->kind())
- {
- case ICompound::Class:
- numClasses++;
- if (hasDocs) numDocClasses++;
- break;
- case ICompound::Struct: numStructs++; break;
- case ICompound::Union: numUnions++; break;
- case ICompound::Interface: numInterfaces++; break;
- case ICompound::Exception: numExceptions++; break;
- case ICompound::Namespace: numNamespaces++; break;
- case ICompound::File: numFiles++; break;
- case ICompound::Group: numGroups++; break;
- case ICompound::Page: numPages++; break;
- default: break;
- }
-
- ISectionIterator *sli = comp->sections();
- ISection *sec;
- for (sli->toFirst();(sec=sli->current());sli->toNext())
- {
- IMemberIterator *mli = sec->members();
- IMember *mem;
- for (mli->toFirst();(mem=mli->current());mli->toNext())
- {
- IParamIterator *pli = mem->parameters();
- IParam *par;
- if (comp->kind()==ICompound::Class ||
- comp->kind()==ICompound::Struct ||
- comp->kind()==ICompound::Interface
- )
- {
- if (mem->kind()==IMember::Function ||
- mem->kind()==IMember::Prototype ||
- mem->kind()==IMember::Signal ||
- mem->kind()==IMember::Slot ||
- mem->kind()==IMember::DCOP
- ) // is a "method"
- {
- if (mem->section()->isPublic())
- {
- numPubMethods++;
- if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
- {
- numDocPubMethods++;
- }
- }
- else if (mem->section()->isProtected())
- {
- numProMethods++;
- if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
- {
- numDocProMethods++;
- }
- }
- else if (mem->section()->isPrivate())
- {
- numPriMethods++;
- if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
- {
- numDocPriMethods++;
- }
- }
- }
- else if (mem->kind()==IMember::Variable ||
- mem->kind()==IMember::Property
- ) // is an "attribute"
- {
- numAttributes++;
- if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
- {
- numDocAttributes++;
- }
- }
- }
- else if (comp->kind()==ICompound::File ||
- comp->kind()==ICompound::Namespace
- )
- {
- if (mem->kind()==IMember::Function ||
- mem->kind()==IMember::Prototype ||
- mem->kind()==IMember::Signal ||
- mem->kind()==IMember::Slot ||
- mem->kind()==IMember::DCOP
- ) // is a "method"
- {
- numFunctions++;
- if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
- {
- numDocFunctions++;
- }
- }
- else if (mem->kind()==IMember::Variable ||
- mem->kind()==IMember::Property
- ) // is an "attribute"
- {
- numVariables++;
- if (isDocumented(mem->briefDescription(),mem->detailedDescription()))
- {
- numDocVariables++;
- }
- }
- }
-
- for (pli->toFirst();(par=pli->current());pli->toNext())
- {
- numParams++;
- }
- const char *type = mem->typeString()->latin1();
- if (type && strcmp(type, "void"))
- {
- numParams++; // count non-void return types as well
- }
- pli->release();
- }
- mli->release();
- }
- sli->release();
-
- comp->release();
- }
- cli->release();
-
- dox->release();
-
- int numMethods = numPubMethods+numProMethods+numPriMethods;
- int numDocMethods = numDocPubMethods+numDocProMethods+numDocPriMethods;
-
- printf("Metrics:\n");
- printf("-----------------------------------\n");
- if (numClasses>0) printf("Classes: %10d (%d documented)\n",numClasses,numDocClasses);
- if (numStructs>0) printf("Structs: %10d\n",numStructs);
- if (numUnions>0) printf("Unions: %10d\n",numUnions);
- if (numInterfaces>0) printf("Interfaces: %10d\n",numInterfaces);
- if (numExceptions>0) printf("Exceptions: %10d\n",numExceptions);
- if (numNamespaces>0) printf("Namespaces: %10d\n",numNamespaces);
- if (numFiles>0) printf("Files: %10d\n",numFiles);
- if (numGroups>0) printf("Groups: %10d\n",numGroups);
- if (numPages>0) printf("Pages: %10d\n",numPages);
- if (numPackages>0) printf("Packages: %10d\n",numPackages);
- if (numMethods>0) printf("Methods: %10d (%d documented)\n",numMethods,numDocMethods);
- if (numPubMethods>0) printf(" Public: %10d (%d documented)\n",numPubMethods,numDocPubMethods);
- if (numProMethods>0) printf(" Protected: %10d (%d documented)\n",numProMethods,numDocProMethods);
- if (numPriMethods>0) printf(" Private: %10d (%d documented)\n",numPriMethods,numDocPriMethods);
- if (numFunctions>0) printf("Functions: %10d (%d documented)\n",numFunctions,numDocFunctions);
- if (numAttributes>0) printf("Attributes: %10d (%d documented)\n",numAttributes,numDocAttributes);
- if (numVariables>0) printf("Variables: %10d (%d documented)\n",numVariables,numDocVariables);
- if (numParams>0) printf("Params: %10d\n",numParams);
- printf("-----------------------------------\n");
- if (numClasses>0) printf("Avg. #methods/compound: %10f\n",(double)numMethods/(double)numClasses);
- if (numMethods>0) printf("Avg. #params/method: %10f\n",(double)numParams/(double)numMethods);
- printf("-----------------------------------\n");
-
- return 0;
-}
-
diff --git a/addon/doxmlparser/examples/metrics/metrics.py b/addon/doxmlparser/examples/metrics/metrics.py
new file mode 100644
index 0000000..a83e16f
--- /dev/null
+++ b/addon/doxmlparser/examples/metrics/metrics.py
@@ -0,0 +1,225 @@
+# An example showing how to use the python doxmlparser module to extract some metrics from
+# the XML output generated by doxygen for a project.
+
+import sys
+
+import doxmlparser
+
+from doxmlparser.compound import DoxCompoundKind, DoxMemberKind, DoxSectionKind, MixedContainer
+
+class Metrics:
+ def __init__(self):
+ self.numClasses = 0
+ self.numDocClasses = 0
+ self.numStructs = 0
+ self.numUnions = 0
+ self.numInterfaces = 0
+ self.numExceptions = 0
+ self.numNamespaces = 0
+ self.numFiles = 0
+ self.numDocFiles = 0
+ self.numGroups = 0
+ self.numPages = 0
+ self.numPubMethods = 0
+ self.numDocPubMethods = 0
+ self.numProMethods = 0
+ self.numDocProMethods = 0
+ self.numPriMethods = 0
+ self.numDocPriMethods = 0
+ self.numAttributes = 0
+ self.numDocAttributes = 0
+ self.numFunctions = 0
+ self.numDocFunctions = 0
+ self.numVariables = 0
+ self.numDocVariables = 0
+ self.numParams = 0
+ def print(self):
+ numMethods = self.numPubMethods + self.numProMethods + self.numPriMethods
+ numDocMethods = self.numDocPubMethods + self.numDocProMethods + self.numDocPriMethods
+ print("Metrics:");
+ print("-----------------------------------");
+ if self.numClasses>0:
+ print("Classes: {:=10} ({} documented)".format(self.numClasses,self.numDocClasses))
+ if self.numStructs>0:
+ print("Structs: {:=10}".format(self.numStructs))
+ if self.numUnions>0:
+ print("Unions: {:=10}".format(self.numUnions))
+ if self.numExceptions>0:
+ print("Exceptions: {:=10}".format(self.numExceptions))
+ if self.numNamespaces>0:
+ print("Namespaces: {:=10}".format(self.numNamespaces))
+ if self.numFiles>0:
+ print("Files: {:=10} ({} documented)".format(self.numFiles,self.numDocFiles))
+ if self.numGroups>0:
+ print("Groups: {:=10}".format(self.numGroups))
+ if self.numPages>0:
+ print("Pages: {:=10}".format(self.numPages))
+ if numMethods>0:
+ print("Methods: {:=10} ({} documented)".format(numMethods,numDocMethods))
+ if self.numPubMethods>0:
+ print(" Public: {:=10} ({} documented)".format(self.numPubMethods,self.numDocPubMethods))
+ if self.numProMethods>0:
+ print(" Protected: {:=10} ({} documented)".format(self.numProMethods,self.numDocProMethods))
+ if self.numPriMethods>0:
+ print(" Private: {:=10} ({} documented)".format(self.numPriMethods,self.numDocPriMethods))
+ if self.numFunctions>0:
+ print("Functions: {:=10} ({} documented)".format(self.numFunctions,self.numDocFunctions))
+ if self.numAttributes>0:
+ print("Attributes: {:=10} ({} documented)".format(self.numAttributes,self.numDocAttributes))
+ if self.numVariables>0:
+ print("Variables: {:=10} ({} documented)".format(self.numVariables,self.numDocVariables))
+ if self.numParams>0:
+ print("Params: {:=10}".format(self.numParams))
+ print("-----------------------------------");
+ if self.numClasses>0:
+ print("Avg. #methods/compound: {:=10}".format(float(numMethods)/float(self.numClasses)))
+ if numMethods>0:
+ print("Avg. #params/method: {:=10}".format(float(self.numParams)/float(numMethods)))
+ print("-----------------------------------");
+
+
+def description_is_empty(description):
+ for content in description.content_:
+ if content.getCategory()==MixedContainer.CategoryText:
+ if not content.getValue().isspace():
+ return False # non space-only text
+ elif not content.getCategory()==MixedContainer.CategoryNone:
+ return False # some internal object like a paragraph
+ return True
+
+def is_documented(definition):
+ return not description_is_empty(definition.get_briefdescription()) or \
+ not description_is_empty(definition.get_detaileddescription())
+
+def section_is_protected(sectionkind):
+ return sectionkind in [DoxSectionKind.PROTECTEDTYPE,
+ DoxSectionKind.PROTECTEDFUNC,
+ DoxSectionKind.PROTECTEDATTRIB,
+ DoxSectionKind.PROTECTEDSLOT,
+ DoxSectionKind.PROTECTEDSTATICFUNC,
+ DoxSectionKind.PROTECTEDSTATICATTRIB]
+
+def section_is_private(sectionkind):
+ return sectionkind in [DoxSectionKind.PRIVATETYPE,
+ DoxSectionKind.PRIVATEFUNC,
+ DoxSectionKind.PRIVATEATTRIB,
+ DoxSectionKind.PRIVATESLOT,
+ DoxSectionKind.PRIVATESTATICFUNC,
+ DoxSectionKind.PRIVATESTATICATTRIB]
+
+def section_is_public(sectionkind):
+ return not section_is_protected(sectionkind) and not section_is_private(sectionkind)
+
+def linked_text_to_string(linkedtext):
+ str=''
+ if linkedtext:
+ for text_or_ref in linkedtext.content_:
+ if text_or_ref.getCategory()==MixedContainer.CategoryText:
+ str+=text_or_ref.getValue()
+ else:
+ str+=text_or_ref.getValue().get_valueOf_()
+ return str
+
+def parse_members(compounddef,sectiondef,metrics):
+ functionLikeKind = [DoxMemberKind.FUNCTION,
+ DoxMemberKind.PROTOTYPE,
+ DoxMemberKind.SIGNAL,
+ DoxMemberKind.SLOT,
+ DoxMemberKind.DCOP]
+ variableLikeKind = [DoxMemberKind.VARIABLE, DoxMemberKind.PROPERTY]
+ for memberdef in sectiondef.get_memberdef():
+ if compounddef.get_kind() in [DoxCompoundKind.CLASS, DoxCompoundKind.STRUCT, DoxCompoundKind.INTERFACE]:
+ if memberdef.get_kind() in functionLikeKind:
+ if section_is_public(sectiondef.get_kind()):
+ metrics.numPubMethods+=1
+ if is_documented(memberdef):
+ metrics.numDocPubMethods+=1
+ elif section_is_protected(sectiondef.get_kind()):
+ metrics.numProMethods+=1
+ if is_documented(memberdef):
+ metrics.numDocProMethods+=1
+ elif section_is_private(sectiondef.get_kind()):
+ metrics.numPriMethods+=1
+ if is_documented(memberdef):
+ metrics.numDocPriMethods+=1
+ elif memberdef.get_kind() in variableLikeKind:
+ metrics.numAttributes+=1
+ if is_documented(memberdef):
+ metrics.numDocAttributes+=1
+ elif compounddef.get_kind() in [DoxCompoundKind.FILE, DoxCompoundKind.NAMESPACE]:
+ if memberdef.get_kind() in functionLikeKind:
+ metrics.numFunctions+=1
+ if is_documented(memberdef):
+ metrics.numDocFunctions+=1
+ elif memberdef.get_kind() in variableLikeKind:
+ metrics.numVariables+=1
+ if is_documented(memberdef):
+ metrics.numDocVariables+=1
+ #for param in memberdef.get_param():
+ # name = ''
+ # if param.get_defname():
+ # name = param.get_defname()
+ # if param.get_declname():
+ # name = param.get_declname()
+ # print("param '{}':'{}'".format(linked_text_to_string(param.get_type()),name))
+ metrics.numParams+=len(memberdef.get_param())
+ if memberdef.get_type() and memberdef.get_type()!="void" and linked_text_to_string(memberdef.get_type()):
+ metrics.numParams+=1 # count non-void return types as well
+ #print("returns '{}'".format(linked_text_to_string(memberdef.get_type())))
+
+def parse_sections(compounddef,metrics):
+ for sectiondef in compounddef.get_sectiondef():
+ parse_members(compounddef,sectiondef,metrics)
+
+def parse_compound(inDirName,baseName,metrics):
+ rootObj = doxmlparser.compound.parse(inDirName+"/"+baseName+".xml",True)
+ for compounddef in rootObj.get_compounddef():
+ kind = compounddef.get_kind()
+ if kind==DoxCompoundKind.CLASS:
+ metrics.numClasses+=1
+ if is_documented(compounddef):
+ metrics.numDocClasses+=1
+ elif kind==DoxCompoundKind.STRUCT:
+ metrics.numStructs+=1
+ elif kind==DoxCompoundKind.UNION:
+ metrics.numUnions+=1
+ elif kind==DoxCompoundKind.INTERFACE:
+ metrics.numInterfaces+=1
+ elif kind==DoxCompoundKind.EXCEPTION:
+ metrics.numExceptions+=1
+ elif kind==DoxCompoundKind.NAMESPACE:
+ metrics.numNamespaces+=1
+ elif kind==DoxCompoundKind.FILE:
+ metrics.numFiles+=1
+ if is_documented(compounddef):
+ metrics.numDocFiles+=1
+ elif kind==DoxCompoundKind.GROUP:
+ metrics.numGroups+=1
+ elif kind==DoxCompoundKind.PAGE:
+ metrics.numPages+=1
+ else:
+ continue
+ parse_sections(compounddef,metrics)
+
+def parse_index(inDirName):
+ metrics = Metrics()
+ rootObj = doxmlparser.index.parse(inDirName+"/index.xml",True)
+ for compound in rootObj.get_compound(): # for each compound defined in the index
+ print("Processing {0}...".format(compound.get_name()))
+ parse_compound(inDirName,compound.get_refid(),metrics)
+ metrics.print()
+
+def usage():
+ print("Usage {0} <xml_output_dir>".format(sys.argv[0]))
+ sys.exit(1)
+
+def main():
+ args = sys.argv[1:]
+ if len(args)==1:
+ parse_index(args[0])
+ else:
+ usage()
+
+if __name__ == '__main__':
+ main()
+