User:Bugman/subsystems
From FlightGear wiki
< User:Bugman
Jump to navigation
Jump to search
Tracking down subsystems
Script
The following script is for finding all FlightGear dependencies:
Python script: Python script for finding all subsystems within the flightgear and simgear C++ code bases.
This script requires the grep Unix command, which can be installed on any OS. And it must be run with Python3.
#! /usr/bin/env python3
# Python module imports.
import operator
from re import search, split
from subprocess import PIPE, Popen
import sys
# Source code repository paths.
SIMGEAR_PATH = "/flightgear/src/flightgear-simgear"
FLIGHTGEAR_PATH = "/flightgear/src/flightgear-flightgear"
class FindSubsystems:
"""Class for finding all subsystems and subsystem groups."""
def __init__(self):
"""Find all subsystems and subsystem groups."""
# SGSubsystem storage lists.
self.subsystems = [[], [], [], []]
self.groups = [[], [], [], []]
# The base objects.
subsystem_base = Subsystem("SGSubsystem")
group_base = Subsystem("SGSubsystemGroup", base_class=Subsystem("SGSubsystem"))
# 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"))
# Find all SGSubsystem and SGSubsystemGroup derived classes.
paths = [SIMGEAR_PATH, FLIGHTGEAR_PATH]
printout = [False, True]
for i in range(len(paths)):
self.find_primary(path=paths[i], text="classes", primary=self.subsystems[0], base_name="SGSubsystem", base=subsystem_base, skip=["SGSubsystemGroup"], printout=printout[i])
self.find_primary(path=paths[i], text="groups", primary=self.groups[0], base_name="SGSubsystemGroup", base=group_base, printout=printout[i])
self.find_secondary(path=paths[i], text="classes", primary=self.subsystems[0], secondary=self.subsystems[1], printout=printout[i])
self.find_secondary(path=paths[i], text="groups", primary=self.groups[0], secondary=self.groups[1], printout=printout[i])
self.find_tertiary(path=paths[i], text="classes", secondary=self.subsystems[1], tertiary=self.subsystems[2], printout=printout[i])
self.find_tertiary(path=paths[i], text="groups", secondary=self.groups[1], tertiary=self.groups[2], 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])
# Final summary.
print("\nTotal: %i subsystem classes." % len(self.subsystems[0] + self.subsystems[1] + self.subsystems[2] + self.subsystems[3]))
print("Total: %i subsystem groups." % len(self.groups[0] + self.groups[1] + self.groups[2] + self.groups[3]))
def count(self, storage_list):
"""Count the number of subsystems and subsystem groups.
@param storage_list: The data structure to count.
@type storage_list: list of Subsystem instances
@return: The number of subsystems and number of groups.
@rtype: int, int
"""
# Init.
subsystems = 0
groups = 0
for element in storage_list:
if element.is_group():
groups += 1
else:
subsystems += 1
# Return the counts.
return subsystems, groups
def find_primary(self, path=None, text=None, primary=None, base_name=None, base=None, skip=[], printout=False):
"""Find all primary subsystems and groups
@keyword path: The path to the repository to search through.
@type path: str
@keyword text: Text identifying subsystems vs. subsystem groups.
@type text: str
@keyword primary: The primary list of subsystems or groups.
@type primary: list of Subsystem instances
@keyword base_name: The name of the base class.
@type base_name: str
@keyword base: The base class object.
@type base: Subsystem instance
@keyword skip: A list of class names to skip.
@type skip: list of str
@keyword printout: A flag which if True will activate the printout of subsystems.
@type printout: bool
"""
# Find all subsystems or groups.
for file_name, class_name in self.grep(path=path, base_name=base_name):
if class_name in skip:
continue
primary.append(Subsystem(class_name, base_class=base, file_name=file_name))
# Sort the subsystems by name.
primary.sort(key=operator.attrgetter('name'))
# Printout.
if printout:
counts = self.count(primary)
print("\nPrimary %s (%i subsystems, %i groups):" % (text, counts[0], counts[1]))
for subsystem in primary:
print(" %s" % subsystem)
def find_secondary(self, path=None, text=None, primary=None, secondary=None, printout=False):
"""Find all secondary subsystems and groups
@keyword path: The path to the repository to search through.
@type path: str
@keyword text: Text identifying subsystems vs. subsystem groups.
@type text: str
@keyword primary: The primary list of subsystems or groups.
@type primary: list of Subsystem instances
@keyword secondary: The secondary list of subsystems or groups.
@type secondary: list of Subsystem instances
@keyword printout: A flag which if True will activate the printout of subsystems.
@type printout: bool
"""
# Loop over all primary subsystems.
for subsystem in primary:
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))
# Sort the subsystems by name.
secondary.sort(key=operator.attrgetter('name'))
# Printout.
if printout and secondary:
counts = self.count(secondary)
print("\nSecondary %s (%i subsystems, %i groups):" % (text, counts[0], counts[1]))
for subsystem in secondary:
print(" %s" % subsystem)
def find_tertiary(self, path=None, text=None, secondary=None, tertiary=None, printout=False):
"""Find all tertiary subsystems and groups
@keyword path: The path to the repository to search through.
@type path: str
@keyword text: Text identifying subsystems vs. subsystem groups.
@type text: str
@keyword secondary: The secondary list of subsystems or groups.
@type secondary: list of Subsystem instances
@keyword tertiary: The tertiary list of subsystems or groups.
@type tertiary: list of Subsystem instances
@keyword printout: A flag which if True will activate the printout of subsystems.
@type printout: bool
"""
# Loop over all secondary subsystems.
for subsystem in secondary:
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))
# Sort all subsystems by name.
tertiary.sort(key=operator.attrgetter('name'))
# Printout.
if printout and tertiary:
counts = self.count(tertiary)
print("\nTertiary %s (%i subsystems, %i groups):" % (text, counts[0], counts[1]))
for subsystem in tertiary:
print(" %s" % subsystem)
def find_quaternary(self, path=None, text=None, tertiary=None, quaternary=None, printout=False):
"""Find all tertiary subsystems and groups
@keyword path: The path to the repository to search through.
@type path: str
@keyword text: Text identifying subsystems vs. subsystem groups.
@type text: str
@keyword tertiary: The tertiary list of subsystems or groups.
@type tertiary: list of Subsystem instances
@keyword quaternary: The quaternary list of subsystems or groups.
@type quaternary: list of Subsystem instances
@keyword printout: A flag which if True will activate the printout of subsystems.
@type printout: bool
"""
# Loop over all tertiary subsystems.
for subsystem in tertiary:
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))
# Sort all subsystems by name.
quaternary.sort(key=operator.attrgetter('name'))
# Printout.
if printout and quaternary:
counts = self.count(quaternary)
print("\nQuaternary %s (%i subsystems, %i groups):" % (text, counts[0], counts[1]))
for subsystem in quaternary:
print(" %s" % subsystem)
def grep(self, path=None, base_name=None):
"""Generator method for finding all classes derived from the given base name and repository.
@keyword path: The path to the repository to search through.
@type path: str
@keyword base_name: The name of the base class.
@type base_name: str
@return: The source file and the name of the derived class.
@rtype: str, str
"""
# The Unix grep command to run.
cmd = 'cd %s; grep -rI "public \<%s\>"
All subsystems
The result is:
Text output: Output from the Python script for finding all subsystems within the C++ code base.
Skipping: 'src/FDM/SP/AISim.hpp: : public FGInterface'
Primary classes (83):
<ADF (from SGSubsystem)>
<AirportDynamicsManager (from SGSubsystem)>
<AirspeedIndicator (from SGSubsystem)>
<Altimeter (from SGSubsystem)>
<AreaSampler (from SGSubsystem)>
<AttitudeIndicator (from SGSubsystem)>
<Clock (from SGSubsystem)>
<CommRadio (from SGSubsystem)>
<Component (from SGSubsystem)>
<DCLGPS (from SGSubsystem)>
<DME (from SGSubsystem)>
<Ephemeris (from SGSubsystem)>
<FDMShell (from SGSubsystem)>
<FGAIManager (from SGSubsystem)>
<FGATCManager (from SGSubsystem)>
<FGAircraftModel (from SGSubsystem)>
<FGCom (from SGSubsystem)>
<FGControls (from SGSubsystem)>
<FGDNSClient (from SGSubsystem)>
<FGElectricalSystem (from SGSubsystem)>
<FGEventInput (from SGSubsystem)>
<FGFX (from SGSubsystem)>
<FGFlightHistory (from SGSubsystem)>
<FGHTTPClient (from SGSubsystem)>
<FGHttpd (from SGSubsystem)>
<FGIO (from SGSubsystem)>
<FGInterface (from SGSubsystem)>
<FGJoystickInput (from SGSubsystem)>
<FGKR_87 (from SGSubsystem)>
<FGKeyboardInput (from SGSubsystem)>
<FGLight (from SGSubsystem)>
<FGLogger (from SGSubsystem)>
<FGMagVarManager (from SGSubsystem)>
<FGMarkerBeacon (from SGSubsystem)>
<FGModelMgr (from SGSubsystem)>
<FGMouseInput (from SGSubsystem)>
<FGMultiplayMgr (from SGSubsystem)>
<FGNasalSys (from SGSubsystem)>
<FGNavRadio (from SGSubsystem)>
<FGPanel (from SGSubsystem)>
<FGPanelProtocol (from SGSubsystem)>
<FGPrecipitationMgr (from SGSubsystem)>
<FGProperties (from SGSubsystem)>
<FGReplay (from SGSubsystem)>
<FGRidgeLift (from SGSubsystem)>
<FGRouteMgr (from SGSubsystem)>
<FGScenery (from SGSubsystem)>
<FGSoundManager (from SGSubsystem)>
<FGSubmodelMgr (from SGSubsystem)>
<FGTrafficManager (from SGSubsystem)>
<FGViewMgr (from SGSubsystem)>
<FGVoiceMgr (from SGSubsystem)>
<GPS (from SGSubsystem)>
<GSDI (from SGSubsystem)>
<GUIMgr (from SGSubsystem)>
<GroundRadar (from SGSubsystem)>
<HUD (from SGSubsystem)>
<HeadingIndicator (from SGSubsystem)>
<HeadingIndicatorDG (from SGSubsystem)>
<HeadingIndicatorFG (from SGSubsystem)>
<InstVerticalSpeedIndicator (from SGSubsystem)>
<LayerInterpolateController (from SGSubsystem)>
<MK_VIII (from SGSubsystem)>
<MagCompass (from SGSubsystem)>
<MasterReferenceGyro (from SGSubsystem)>
<NavDisplay (from SGSubsystem)>
<NavRadio (from SGSubsystem)>
<NewGUI (from SGSubsystem)>
<PerformanceDB (from SGSubsystem)>
<PitotSystem (from SGSubsystem)>
<RadarAltimeter (from SGSubsystem)>
<RealWxController (from SGSubsystem)>
<SlipSkidBall (from SGSubsystem)>
<StaticSystem (from SGSubsystem)>
<TACAN (from SGSubsystem)>
<TCAS (from SGSubsystem)>
<TimeManager (from SGSubsystem)>
<Transponder (from SGSubsystem)>
<TurnIndicator (from SGSubsystem)>
<VacuumSystem (from SGSubsystem)>
<VerticalSpeedIndicator (from SGSubsystem)>
<View (from SGSubsystem)>
<wxRadarBg (from SGSubsystem)>
Secondary classes (25):
<AnalogComponent (from Component : SGSubsystem)>
<BasicRealWxController (from RealWxController : SGSubsystem)>
<CommRadioImpl (from CommRadio : SGSubsystem)>
<DigitalComponent (from Component : SGSubsystem)>
<FGACMS (from FGInterface : SGSubsystem)>
<FGADA (from FGInterface : SGSubsystem)>
<FGBalloonSim (from FGInterface : SGSubsystem)>
<FGExternalNet (from FGInterface : SGSubsystem)>
<FGExternalPipe (from FGInterface : SGSubsystem)>
<FGHIDEventInput (from FGEventInput : SGSubsystem)>
<FGJSBsim (from FGInterface : SGSubsystem)>
<FGLaRCsim (from FGInterface : SGSubsystem)>
<FGLinuxEventInput (from FGEventInput : SGSubsystem)>
<FGMacOSXEventInput (from FGEventInput : SGSubsystem)>
<FGMagicCarpet (from FGInterface : SGSubsystem)>
<FGNullFDM (from FGInterface : SGSubsystem)>
<FGReadablePanel (from FGPanel : SGSubsystem)>
<FGUFO (from FGInterface : SGSubsystem)>
<KLN89 (from DCLGPS : SGSubsystem)>
<LayerInterpolateControllerImplementation (from LayerInterpolateController : SGSubsystem)>
<MongooseHttpd (from FGHttpd : SGSubsystem)>
<NavRadioImpl (from NavRadio : SGSubsystem)>
<StateMachineComponent (from Component : SGSubsystem)>
<YASim (from FGInterface : SGSubsystem)>
<agRadar (from wxRadarBg : SGSubsystem)>
Tertiary classes (6):
<DigitalFilter (from AnalogComponent : Component : SGSubsystem)>
<Logic (from DigitalComponent : Component : SGSubsystem)>
<NoaaMetarRealWxController (from BasicRealWxController : RealWxController : SGSubsystem)>
<PIDController (from AnalogComponent : Component : SGSubsystem)>
<PISimpleController (from AnalogComponent : Component : SGSubsystem)>
<Predictor (from AnalogComponent : Component : SGSubsystem)>
Quaternary classes (1):
<FlipFlop (from Logic : DigitalComponent : Component : SGSubsystem)>
Total: 115 subsystem classes.
Refactoring
To check that all subsystems on a branch have been updated or refactored:
Python script: Python script verifying if all subsystems have been updated.
#! /usr/bin/env python3
from find_subsystems import FindSubsystems
from subprocess import PIPE, Popen
class ToUpdate:
def __init__(self):
subsystems = FindSubsystems()
pipe = Popen("git diff --name-only ..next", shell=True, stdout=PIPE)
blacklist = []
for line in pipe.stdout.readlines():
file_name = line.decode()
file_name = file_name.strip()
blacklist.append(file_name)
# Loop over all derived classes.
print("\nStill to be updated:")
for subsystem in subsystems.classes_primary + subsystems.classes_secondary + subsystems.classes_tertiary + subsystems.classes_quaternary:
if subsystem.file_name in blacklist:
continue
print(" %s: %s" % (subsystem.file_name, subsystem))
if __name__ == "__main__":
ToUpdate()