diff options
author | Dimitri van Heesch <doxygen@gmail.com> | 2021-02-02 20:21:27 (GMT) |
---|---|---|
committer | Dimitri van Heesch <doxygen@gmail.com> | 2021-02-02 20:34:58 (GMT) |
commit | 095c5de5e4df192898f7f13e9b51524999615983 (patch) | |
tree | 2d04e5aacb490898ed8053100cc1eca334f6be4a /addon/doxmlparser/examples | |
parent | cd3c39c11084a326baee2e81420fe13a5dacb8e2 (diff) | |
download | Doxygen-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.txt | 2 | ||||
-rw-r--r-- | addon/doxmlparser/examples/dump/dump.py | 31 | ||||
-rw-r--r-- | addon/doxmlparser/examples/metrics/CMakeLists.txt | 18 | ||||
-rw-r--r-- | addon/doxmlparser/examples/metrics/main.cpp | 271 | ||||
-rw-r--r-- | addon/doxmlparser/examples/metrics/metrics.py | 225 |
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() + |