User:Bugman/subsystems: Difference between revisions

From FlightGear wiki
Jump to navigation Jump to search
(→‎All subsystems: Updated the output to match the newest script.)
(→‎Script: Yet another script update.)
Line 15: Line 15:
# Python module imports.
# Python module imports.
import operator
import operator
from os import access, F_OK, sep
from re import search, split
from re import search, split
from subprocess import PIPE, Popen
from subprocess import PIPE, Popen
Line 23: Line 24:
SIMGEAR_PATH = "/flightgear/src/flightgear-simgear"
SIMGEAR_PATH = "/flightgear/src/flightgear-simgear"
FLIGHTGEAR_PATH = "/flightgear/src/flightgear-flightgear"
FLIGHTGEAR_PATH = "/flightgear/src/flightgear-flightgear"
# Directories to exclude from the grep.
EXCLUDE_DIR = [
    ".git",
    "build*"
]




Line 39: Line 46:
         self.subsystems = [[], [], [], []]
         self.subsystems = [[], [], [], []]
         self.groups = [[], [], [], []]
         self.groups = [[], [], [], []]
        # Grep exclude options.
        self.grep_exclude_dir = ""
        for name in EXCLUDE_DIR:
            self.grep_exclude_dir += "--exclude-dir \"%s\" " % name


         # The base objects.
         # The base objects.
Line 45: Line 57:


         # Add some problematic non-parsable classes.
         # Add some problematic non-parsable classes.
         self.subsystems[1].append(Subsystem("FGAISim", base_class=Subsystem("FGInterface", base_class=Subsystem("SGSubsystem")), file_name="src/FDM/SP/AISim.hpp", xml=self.xml))
         self.subsystems[1].append(Subsystem("FGAISim", base_class=Subsystem("FGInterface", base_class=Subsystem("SGSubsystem")), declaration_file="src/FDM/SP/AISim.hpp", xml=self.xml))


         # XML start.
         # XML start.
Line 66: Line 78:
             self.find_quaternary(path=paths[i], text="classes", tertiary=self.subsystems[2], quaternary=self.subsystems[3], printout=printout[i])
             self.find_quaternary(path=paths[i], text="classes", tertiary=self.subsystems[2], quaternary=self.subsystems[3], printout=printout[i])
             self.find_quaternary(path=paths[i], text="groups", tertiary=self.groups[2], quaternary=self.groups[3], printout=printout[i])
             self.find_quaternary(path=paths[i], text="groups", tertiary=self.groups[2], quaternary=self.groups[3], printout=printout[i])
        # Find the subsystem and subsystem group implementation files.
        self.find_implementations()


         # Final summary.
         # Final summary.
Line 95: Line 110:
         # Return the counts.
         # Return the counts.
         return subsystems, groups
         return subsystems, groups
    def find_implementations(self):
        """Find all implementation files for all subsystems and subsystem groups."""
        # Loop over all subsystems and groups.
        for subsystem in self.subsystems[0] + self.subsystems[1] + self.subsystems[2] + self.subsystems[3] + self.groups[0] + self.groups[1] + self.groups[2] + self.groups[3]:
            # The repository location.
            if subsystem.declaration_file[:7] == "simgear":
                path = SIMGEAR_PATH
            else:
                path = FLIGHTGEAR_PATH
            # The grep command for the ctor and dtor implementation.
            ctor = "\<%s\>::\<%s\>[ \(]" % (subsystem.name, subsystem.name)
            dtor = "\<%s\>::\~\<%s\>[ \(]" % (subsystem.name, subsystem.name)
            grep_ctor = 'grep -rI "%s\|%s"' % (ctor, dtor)
            # The grep command for any function implementation.
            grep_any = 'grep -rI %s "^[A-Za-z ]*\<%s\>::"' % (self.grep_exclude_dir, subsystem.name)
            # Search for matching file roots.
            if subsystem.declaration_file[-3:] == "hxx":
                # The probable implementation file name.
                file_name = subsystem.declaration_file[:-3] + "cxx"
                full_path = path + sep + file_name
                if access(full_path, F_OK):
                    # The Unix grep commands to run.
                    cmds = [
                        '%s %s' % (grep_ctor, full_path),
                        '%s %s | grep -v "return"' % (grep_any, full_path)
                    ]
                    # Search.
                    for cmd in cmds:
                        print(cmd)
                        pipe = Popen(cmd, shell=True, stdout=PIPE)
                        lines = pipe.stdout.readlines()
                        if len(lines):
                            subsystem.implementation_file = file_name
                            break
            # Search everywhere.
            else:
                # The Unix grep commands to run.
                cmds = [
                    'cd %s; %s' % (path, grep_ctor),
                    'cd %s; %s | grep -v "return"' % (path, grep_any)
                ]
                # Search.
                for cmd in cmds:
                    print(cmd)
                    pipe = Popen(cmd, shell=True, stdout=PIPE)
                    # Read all output.
                    files = []
                    for line in pipe.stdout.readlines():
                        # Convert the byte-array.
                        line = line.decode()
                        # Add the file if not already present.
                        file_name = line.split(":")[0]
                        if file_name not in files:
                            files.append(file_name)
                    # Bad grep.
                    if len(files) > 1:
                        sys.stderr.write("Warning: Excessive grep matching, too many implementation files found for:\n")
                        sys.stderr.write("    %s: %s\n" % (subsystem.name, files))
                    # Store the implementation file.
                    elif len(files):
                        subsystem.implementation_file = files[0]
                        break




Line 116: Line 206:
         """
         """


        # Printout.
         # Find all subsystems or groups.
         # Find all subsystems or groups.
         for file_name, class_name in self.grep(path=path, base_name=base_name):
         for file_name, class_name in self.grep(path=path, base_name=base_name):
             if class_name in skip:
             if class_name in skip:
                 continue
                 continue
             primary.append(Subsystem(class_name, base_class=base, file_name=file_name, xml=self.xml))
             primary.append(Subsystem(class_name, base_class=base, declaration_file=file_name, xml=self.xml))


         # Sort the subsystems by name.
         # Sort the subsystems by name.
Line 156: Line 247:
         for subsystem in primary:
         for subsystem in primary:
             for file_name, derived_class in self.grep(path=path, base_name=subsystem.name):
             for file_name, derived_class in self.grep(path=path, base_name=subsystem.name):
                 secondary.append(Subsystem(derived_class, base_class=subsystem, file_name=file_name, xml=self.xml))
                 secondary.append(Subsystem(derived_class, base_class=subsystem, declaration_file=file_name, xml=self.xml))


         # Sort the subsystems by name.
         # Sort the subsystems by name.
Line 192: Line 283:
         for subsystem in secondary:
         for subsystem in secondary:
             for file_name, derived_class in self.grep(path=path, base_name=subsystem.name):
             for file_name, derived_class in self.grep(path=path, base_name=subsystem.name):
                 tertiary.append(Subsystem(derived_class, base_class=subsystem, file_name=file_name, xml=self.xml))
                 tertiary.append(Subsystem(derived_class, base_class=subsystem, declaration_file=file_name, xml=self.xml))


         # Sort all subsystems by name.
         # Sort all subsystems by name.
Line 228: Line 319:
         for subsystem in tertiary:
         for subsystem in tertiary:
             for file_name, derived_class in self.grep(path=path, base_name=subsystem.name):
             for file_name, derived_class in self.grep(path=path, base_name=subsystem.name):
                 quaternary.append(Subsystem(derived_class, base_class=subsystem, file_name=file_name, xml=self.xml))
                 quaternary.append(Subsystem(derived_class, base_class=subsystem, declaration_file=file_name, xml=self.xml))


         # Sort all subsystems by name.
         # Sort all subsystems by name.
Line 258: Line 349:


         # The Unix grep command to run.
         # The Unix grep command to run.
         cmd = 'cd %s; grep -rI "public \<%s\>" | grep -v "%s::"' % (path, base_name, base_name)
         cmd = 'cd %s; grep -rI %s "public \<%s\>" | grep -v "%s::"' % (path, self.grep_exclude_dir, base_name, base_name)
         pipe = Popen(cmd, shell=True, stdout=PIPE)
         pipe = Popen(cmd, shell=True, stdout=PIPE)


Line 302: Line 393:
         subsystem_groups_flightgear = 0
         subsystem_groups_flightgear = 0
         for subsystem in self.subsystems[0] + self.subsystems[1] + self.subsystems[2] + self.subsystems[3]:
         for subsystem in self.subsystems[0] + self.subsystems[1] + self.subsystems[2] + self.subsystems[3]:
             if subsystem.file_name[:7] == "simgear":
             if subsystem.declaration_file[:7] == "simgear":
                 subsystem_classes_simgear += 1
                 subsystem_classes_simgear += 1
             else:
             else:
                 subsystem_classes_flightgear += 1
                 subsystem_classes_flightgear += 1
         for group in self.groups[0] + self.groups[1] + self.groups[2] + self.groups[3]:
         for group in self.groups[0] + self.groups[1] + self.groups[2] + self.groups[3]:
             if group.file_name[:7] == "simgear":
             if group.declaration_file[:7] == "simgear":
                 subsystem_groups_simgear += 1
                 subsystem_groups_simgear += 1
             else:
             else:
Line 316: Line 407:
         flightgear_total = subsystem_classes_flightgear + subsystem_groups_flightgear
         flightgear_total = subsystem_classes_flightgear + subsystem_groups_flightgear


        # Printout.
         if self.xml:
         if self.xml:
             print("<total subsystem_classes=\"%i\" subsystem_groups=\"%i\" total=\"%i\"/>" % (subsystem_classes, subsystem_groups, subsystem_total))
             print(" <counts>")
             print("<simgear subsystem_classes=\"%i\" subsystem_groups=\"%i\" total=\"%i\"/>" % (subsystem_classes_simgear, subsystem_groups_simgear, simgear_total))
            print("    <simgear>")
             print("<flightgear subsystem_classes=\"%i\" subsystem_groups=\"%i\" total=\"%i\"/>" % (subsystem_classes_flightgear, subsystem_groups_flightgear, flightgear_total))
            print("      <subsystem_classes>%i</subsystem_classes>" % subsystem_classes_simgear)
            print("     <subsystem_groups>%i</subsystem_groups>" % subsystem_groups_simgear)
            print("     <total>%i</total>" % simgear_total)
            print("    </simgear>")
            print("    <flightgear>")
             print("     <subsystem_classes>%i</subsystem_classes>" % subsystem_classes_flightgear)
            print("     <subsystem_groups>%i</subsystem_groups>" % subsystem_groups_flightgear)
            print("     <total>%i</total>" % flightgear_total)
            print("    </flightgear>")
            print("    <combined>")
             print("     <subsystem_classes>%i</subsystem_classes>" % subsystem_classes)
            print("     <subsystem_groups>%i</subsystem_groups>" % subsystem_groups)
            print("     <total>%i</total>" % subsystem_total)
            print("   </combined>")
            print("  </counts>")
         else:
         else:
             print("\nTotal: %i subsystem classes (%i flightgear, %i simgear)." % (subsystem_classes, subsystem_classes_flightgear, subsystem_classes_simgear))
             print("\nCounts: %i subsystem classes (%i flightgear, %i simgear)." % (subsystem_classes, subsystem_classes_flightgear, subsystem_classes_simgear))
             print("Total: %i subsystem groups (%i flightgear, %i simgear)." % (subsystem_groups, subsystem_groups_flightgear, subsystem_groups_simgear))
             print("Counts: %i subsystem groups (%i flightgear, %i simgear)." % (subsystem_groups, subsystem_groups_flightgear, subsystem_groups_simgear))
             print("Total: %i subsystem classes and groups (%i flightgear, %i simgear)." % (subsystem_total, flightgear_total, simgear_total))
             print("Counts: %i subsystem classes and groups (%i flightgear, %i simgear)." % (subsystem_total, flightgear_total, simgear_total))




Line 330: Line 436:
     """Object for storing the information for a specific subsystem."""
     """Object for storing the information for a specific subsystem."""


     def __init__(self, name, base_class=None, file_name=None, xml=False):
     def __init__(self, name, base_class=None, declaration_file=None, implementation_file=None, xml=False):
         """Set up the object.
         """Set up the object.


         @param name:           The name of the subsystem.
         @param name:               The name of the subsystem.
         @type name:             str
         @type name:                 str
         @keyword base_class:   The name of the base class.
         @keyword base_class:       The name of the base class.
         @type base_class:       str
         @type base_class:           str
         @keyword file_name:    The name of the file containing the subsystem declaration.
         @keyword declaration_file:  The name of the file containing the subsystem declaration.
         @type file_name:       str
        @type declaration_file:    str
         @keyword xml:           Produce a valid XML representation of the object.
        @keyword implementation_file:  The name of the file containing the subsystem declaration.
         @type xml:             bool
         @type implementation_file:     str
         @keyword xml:               Produce a valid XML representation of the object.
         @type xml:                 bool
         """
         """


Line 346: Line 454:
         self.name = name
         self.name = name
         self.base_class = base_class
         self.base_class = base_class
         self.file_name = file_name
         self.declaration_file = declaration_file
        self.implementation_file = implementation_file
         self.xml = xml
         self.xml = xml


Line 378: Line 487:
                 string += "\""
                 string += "\""


         # Add the source file name.
         # Add the declaration file name.
         if self.xml:
         if self.xml:
             string += " in="
             string += " declaration="
         else:
         else:
             string += " in "
             string += " in "
         string += "\"%s\"" % self.file_name
         string += "\"%s\"" % self.declaration_file
 
        # Add the implementation file name.
        if self.implementation_file:
            if self.xml:
                string += " implementation="
            else:
                string += ", "
            string += "\"%s\"" % self.implementation_file


         # Closure.
         # Closure.

Revision as of 12:09, 19 April 2018

Tracking down subsystems

Script

The following script is for finding all FlightGear dependencies:

All subsystems

The result is:

Refactoring

To check that all subsystems on a branch have been updated or refactored: