From 9ba8e6cf38da5196ed7bc878fe452952f3e10638 Mon Sep 17 00:00:00 2001 From: Magnus Auvinen Date: Tue, 22 May 2007 15:06:55 +0000 Subject: moved docs --- docs/doctool/Modules/NaturalDocs/Project.pm | 966 ++++++++++++++++++++++++++++ 1 file changed, 966 insertions(+) create mode 100644 docs/doctool/Modules/NaturalDocs/Project.pm (limited to 'docs/doctool/Modules/NaturalDocs/Project.pm') diff --git a/docs/doctool/Modules/NaturalDocs/Project.pm b/docs/doctool/Modules/NaturalDocs/Project.pm new file mode 100644 index 00000000..2575fa4c --- /dev/null +++ b/docs/doctool/Modules/NaturalDocs/Project.pm @@ -0,0 +1,966 @@ +############################################################################### +# +# Package: NaturalDocs::Project +# +############################################################################### +# +# A package that manages information about the files in the source tree, as well as the list of files that have to be parsed +# and built. +# +# Usage and Dependencies: +# +# - All the are available immediately, except for the status functions. +# +# - and are available immediately, because they may need to be called +# after but before . +# +# - Prior to , must be initialized. +# +# - After , the status are available as well. +# +# - Prior to , and must be initialized. +# +# - After , the rest of the are available. +# +############################################################################### + +# This file is part of Natural Docs, which is Copyright (C) 2003-2005 Greg Valure +# Natural Docs is licensed under the GPL + +use NaturalDocs::Project::File; + +use strict; +use integer; + +package NaturalDocs::Project; + + +############################################################################### +# Group: Variables + +# +# handle: FH_FILEINFO +# +# The file handle for the file information file, . +# + + +# +# handle: FH_CONFIGFILEINFO +# +# The file handle for the config file information file, . +# + + +# +# hash: supportedFiles +# +# A hash of all the supported files in the input directory. The keys are the , and the values are +# objects. +# +my %supportedFiles; + +# +# hash: filesToParse +# +# An existence hash of all the that need to be parsed. +# +my %filesToParse; + +# +# hash: filesToBuild +# +# An existence hash of all the that need to be built. +# +my %filesToBuild; + +# +# hash: filesToPurge +# +# An existence hash of the that had Natural Docs content last time, but now either don't exist or no longer have +# content. +# +my %filesToPurge; + +# +# hash: unbuiltFilesWithContent +# +# An existence hash of all the that have Natural Docs content but are not part of . +# +my %unbuiltFilesWithContent; + + +# var: menuFileStatus +# The of the project's menu file. +my $menuFileStatus; + +# var: mainTopicsFileStatus +# The of the project's main topics file. +my $mainTopicsFileStatus; + +# var: userTopicsFileStatus +# The of the project's user topics file. +my $userTopicsFileStatus; + +# var: mainLanguagesFileStatus +# The of the project's main languages file. +my $mainLanguagesFileStatus; + +# var: userLanguagesFileStatus +# The of the project's user languages file. +my $userLanguagesFileStatus; + +# bool: reparseEverything +# Whether all the source files need to be reparsed. +my $reparseEverything; + +# bool: rebuildEverything +# Whether all the source files need to be rebuilt. +my $rebuildEverything; + +# hash: mostUsedLanguage +# The name of the most used language. Doesn't include text files. +my $mostUsedLanguage; + + + +############################################################################### +# Group: Files + + +# +# File: FileInfo.nd +# +# An index of the state of the files as of the last parse. Used to determine if files were added, deleted, or changed. +# +# Format: +# +# The format is a text file. +# +# > [VersionInt: app version] +# +# The beginning of the file is the it was generated with. +# +# > [most used language name] +# +# Next is the name of the most used language in the source tree. Does not include text files. +# +# Each following line is +# +# > [file name] tab [last modification time] tab [has ND content (0 or 1)] tab [default menu title] \n +# +# Revisions: +# +# 1.3: +# +# - The line following the , which was previously the last modification time of , was changed to +# the name of the most used language. +# +# 1.16: +# +# - File names are now absolute. Prior to 1.16, they were relative to the input directory since only one was allowed. +# +# 1.14: +# +# - The file was renamed from NaturalDocs.files to FileInfo.nd and moved into the Data subdirectory. +# +# 0.95: +# +# - The file version was changed to match the program version. Prior to 0.95, the version line was 1. Test for "1" instead +# of "1.0" to distinguish. +# + + +# +# File: ConfigFileInfo.nd +# +# An index of the state of the config files as of the last parse. +# +# Format: +# +# > [BINARY_FORMAT] +# > [VersionInt: app version] +# +# First is the standard header. +# +# > [UInt32: last modification time of menu] +# > [UInt32: last modification of main topics file] +# > [UInt32: last modification of user topics file] +# > [UInt32: last modification of main languages file] +# > [UInt32: last modification of user languages file] +# +# Next are the last modification times of various configuration files as UInt32s in the standard Unix format. +# +# +# Revisions: +# +# 1.3: +# +# - The file was added to Natural Docs. Previously the last modification of was stored in , and +# and didn't exist. +# + + + +############################################################################### +# Group: File Functions + +# +# Function: LoadSourceFileInfo +# +# Loads the project file from disk and compares it against the files in the input directory. Project is loaded from +# . New and changed files will be added to , and if they have content, +# . +# +# Will call OnMostUsedLanguageChange()> if changes. +# +# Returns: +# +# Returns whether the project was changed in any way. +# +sub LoadSourceFileInfo + { + my ($self) = @_; + + $self->GetAllSupportedFiles(); + NaturalDocs::Languages->OnMostUsedLanguageKnown(); + + my $fileIsOkay; + my $version; + my $hasChanged; + + if (open(FH_FILEINFO, '<' . $self->FileInfoFile())) + { + # Check if the file is in the right format. + $version = NaturalDocs::Version->FromTextFile(\*FH_FILEINFO); + + # The project file need to be rebuilt for 1.16. The source files need to be reparsed and the output files rebuilt for 1.35. + # We'll tolerate the difference between 1.16 and 1.3 in the loader. + + if ($version >= NaturalDocs::Version->FromString('1.16') && $version <= NaturalDocs::Settings->AppVersion()) + { + $fileIsOkay = 1; + + if ($version < NaturalDocs::Version->FromString('1.35')) + { + $reparseEverything = 1; + $rebuildEverything = 1; + $hasChanged = 1; + }; + } + else + { + close(FH_FILEINFO); + $hasChanged = 1; + }; + }; + + + if ($fileIsOkay) + { + my %indexedFiles; + + + my $line = ; + ::XChomp(\$line); + + # Prior to 1.3 it was the last modification time of Menu.txt, which we ignore and treat as though the most used language + # changed. Prior to 1.32 the settings didn't transfer over correctly to Menu.txt so we need to behave that way again. + if ($version < NaturalDocs::Version->FromString('1.32') || lc($mostUsedLanguage) ne lc($line)) + { + $reparseEverything = 1; + NaturalDocs::SymbolTable->RebuildAllIndexes(); + }; + + + # Parse the rest of the file. + + while ($line = ) + { + ::XChomp(\$line); + my ($file, $modification, $hasContent, $menuTitle) = split(/\t/, $line, 4); + + # If the file no longer exists... + if (!exists $supportedFiles{$file}) + { + if ($hasContent) + { $filesToPurge{$file} = 1; }; + + $hasChanged = 1; + } + + # If the file still exists... + else + { + $indexedFiles{$file} = 1; + + # If the file changed... + if ($supportedFiles{$file}->LastModified() != $modification) + { + $supportedFiles{$file}->SetStatus(::FILE_CHANGED()); + $filesToParse{$file} = 1; + + # If the file loses its content, this will be removed by SetHasContent(). + if ($hasContent) + { $filesToBuild{$file} = 1; }; + + $hasChanged = 1; + } + + # If the file has not changed... + else + { + my $status; + + if ($rebuildEverything && $hasContent) + { + $status = ::FILE_CHANGED(); + + # If the file loses its content, this will be removed by SetHasContent(). + $filesToBuild{$file} = 1; + $hasChanged = 1; + } + else + { + $status = ::FILE_SAME(); + + if ($hasContent) + { $unbuiltFilesWithContent{$file} = 1; }; + }; + + if ($reparseEverything) + { + $status = ::FILE_CHANGED(); + + $filesToParse{$file} = 1; + $hasChanged = 1; + }; + + $supportedFiles{$file}->SetStatus($status); + }; + + $supportedFiles{$file}->SetHasContent($hasContent); + $supportedFiles{$file}->SetDefaultMenuTitle($menuTitle); + }; + }; + + close(FH_FILEINFO); + + + # Check for added files. + + if (scalar keys %supportedFiles > scalar keys %indexedFiles) + { + foreach my $file (keys %supportedFiles) + { + if (!exists $indexedFiles{$file}) + { + $supportedFiles{$file}->SetStatus(::FILE_NEW()); + $supportedFiles{$file}->SetDefaultMenuTitle($file); + $supportedFiles{$file}->SetHasContent(undef); + $filesToParse{$file} = 1; + # It will be added to filesToBuild if HasContent gets set to true when it's parsed. + $hasChanged = 1; + }; + }; + }; + } + + # If something's wrong with FileInfo.nd, everything is new. + else + { + foreach my $file (keys %supportedFiles) + { + $supportedFiles{$file}->SetStatus(::FILE_NEW()); + $supportedFiles{$file}->SetDefaultMenuTitle($file); + $supportedFiles{$file}->SetHasContent(undef); + $filesToParse{$file} = 1; + # It will be added to filesToBuild if HasContent gets set to true when it's parsed. + }; + + $hasChanged = 1; + }; + + + # There are other side effects, so we need to call this. + if ($rebuildEverything) + { $self->RebuildEverything(); }; + + + return $hasChanged; + }; + + +# +# Function: SaveSourceFileInfo +# +# Saves the source file info to disk. Everything is saved in . +# +sub SaveSourceFileInfo + { + my ($self) = @_; + + open(FH_FILEINFO, '>' . $self->FileInfoFile()) + or die "Couldn't save project file " . $self->FileInfoFile() . "\n"; + + NaturalDocs::Version->ToTextFile(\*FH_FILEINFO, NaturalDocs::Settings->AppVersion()); + + print FH_FILEINFO $mostUsedLanguage . "\n"; + + while (my ($fileName, $file) = each %supportedFiles) + { + print FH_FILEINFO $fileName . "\t" + . $file->LastModified() . "\t" + . ($file->HasContent() || '0') . "\t" + . $file->DefaultMenuTitle() . "\n"; + }; + + close(FH_FILEINFO); + }; + + +# +# Function: LoadConfigFileInfo +# +# Loads the config file info to disk. +# +sub LoadConfigFileInfo + { + my ($self) = @_; + + my $fileIsOkay; + my $version; + my $fileName = NaturalDocs::Project->ConfigFileInfoFile(); + + if (open(FH_CONFIGFILEINFO, '<' . $fileName)) + { + # See if it's binary. + binmode(FH_CONFIGFILEINFO); + + my $firstChar; + read(FH_CONFIGFILEINFO, $firstChar, 1); + + if ($firstChar == ::BINARY_FORMAT()) + { + $version = NaturalDocs::Version->FromBinaryFile(\*FH_CONFIGFILEINFO); + + # It hasn't changed since being introduced. + + if ($version <= NaturalDocs::Settings->AppVersion()) + { $fileIsOkay = 1; } + else + { close(FH_CONFIGFILEINFO); }; + } + + else # it's not in binary + { close(FH_CONFIGFILEINFO); }; + }; + + my @configFiles = ( $self->MenuFile(), \$menuFileStatus, + $self->MainTopicsFile(), \$mainTopicsFileStatus, + $self->UserTopicsFile(), \$userTopicsFileStatus, + $self->MainLanguagesFile(), \$mainLanguagesFileStatus, + $self->UserLanguagesFile(), \$userLanguagesFileStatus ); + + if ($fileIsOkay) + { + my $raw; + + read(FH_CONFIGFILEINFO, $raw, 20); + my @configFileDates = unpack('NNNNN', $raw); + + while (scalar @configFiles) + { + my $file = shift @configFiles; + my $fileStatus = shift @configFiles; + my $fileDate = shift @configFileDates; + + if (-e $file) + { + if ($fileDate == (stat($file))[9]) + { $$fileStatus = ::FILE_SAME(); } + else + { $$fileStatus = ::FILE_CHANGED(); }; + } + else + { $$fileStatus = ::FILE_DOESNTEXIST(); }; + }; + + close(FH_CONFIGFILEINFO); + } + else + { + while (scalar @configFiles) + { + my $file = shift @configFiles; + my $fileStatus = shift @configFiles; + + if (-e $file) + { $$fileStatus = ::FILE_CHANGED(); } + else + { $$fileStatus = ::FILE_DOESNTEXIST(); }; + }; + }; + + if ($menuFileStatus == ::FILE_SAME() && $rebuildEverything) + { $menuFileStatus = ::FILE_CHANGED(); }; + }; + + +# +# Function: SaveConfigFileInfo +# +# Saves the config file info to disk. You *must* save all other config files first, such as and . +# +sub SaveConfigFileInfo + { + my ($self) = @_; + + open (FH_CONFIGFILEINFO, '>' . NaturalDocs::Project->ConfigFileInfoFile()) + or die "Couldn't save " . NaturalDocs::Project->ConfigFileInfoFile() . ".\n"; + + binmode(FH_CONFIGFILEINFO); + + print FH_CONFIGFILEINFO '' . ::BINARY_FORMAT(); + + NaturalDocs::Version->ToBinaryFile(\*FH_CONFIGFILEINFO, NaturalDocs::Settings->AppVersion()); + + print FH_CONFIGFILEINFO pack('NNNNN', (stat($self->MenuFile()))[9], + (stat($self->MainTopicsFile()))[9], + (stat($self->UserTopicsFile()))[9], + (stat($self->MainLanguagesFile()))[9], + (stat($self->UserLanguagesFile()))[9] ); + + close(FH_CONFIGFILEINFO); + }; + + +# +# Function: MigrateOldFiles +# +# If the project uses the old file names used prior to 1.14, it converts them to the new file names. +# +sub MigrateOldFiles + { + my ($self) = @_; + + my $projectDirectory = NaturalDocs::Settings->ProjectDirectory(); + + # We use the menu file as a test to see if we're using the new format. + if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs_Menu.txt')) + { + # The Data subdirectory would have been created by NaturalDocs::Settings. + + rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs_Menu.txt'), $self->MenuFile() ); + + if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.sym')) + { rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.sym'), $self->SymbolTableFile() ); }; + + if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.files')) + { rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.files'), $self->FileInfoFile() ); }; + + if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.m')) + { rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.m'), $self->PreviousMenuStateFile() ); }; + }; + }; + + + +############################################################################### +# Group: Data File Functions + + +# Function: FileInfoFile +# Returns the full path to the file information file. +sub FileInfoFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDataDirectory(), 'FileInfo.nd' ); }; + +# Function: ConfigFileInfoFile +# Returns the full path to the config file information file. +sub ConfigFileInfoFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDataDirectory(), 'ConfigFileInfo.nd' ); }; + +# Function: SymbolTableFile +# Returns the full path to the symbol table's data file. +sub SymbolTableFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDataDirectory(), 'SymbolTable.nd' ); }; + +# Function: ClassHierarchyFile +# Returns the full path to the class hierarchy's data file. +sub ClassHierarchyFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDataDirectory(), 'ClassHierarchy.nd' ); }; + +# Function: MenuFile +# Returns the full path to the project's menu file. +sub MenuFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDirectory(), 'Menu.txt' ); }; + +# Function: MenuFileStatus +# Returns the of the project's menu file. +sub MenuFileStatus + { return $menuFileStatus; }; + +# Function: MainTopicsFile +# Returns the full path to the main topics file. +sub MainTopicsFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ConfigDirectory(), 'Topics.txt' ); }; + +# Function: MainTopicsFileStatus +# Returns the of the project's main topics file. +sub MainTopicsFileStatus + { return $mainTopicsFileStatus; }; + +# Function: UserTopicsFile +# Returns the full path to the user's topics file. +sub UserTopicsFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDirectory(), 'Topics.txt' ); }; + +# Function: UserTopicsFileStatus +# Returns the of the project's user topics file. +sub UserTopicsFileStatus + { return $userTopicsFileStatus; }; + +# Function: MainLanguagesFile +# Returns the full path to the main languages file. +sub MainLanguagesFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ConfigDirectory(), 'Languages.txt' ); }; + +# Function: MainLanguagesFileStatus +# Returns the of the project's main languages file. +sub MainLanguagesFileStatus + { return $mainLanguagesFileStatus; }; + +# Function: UserLanguagesFile +# Returns the full path to the user's languages file. +sub UserLanguagesFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDirectory(), 'Languages.txt' ); }; + +# Function: UserLanguagesFileStatus +# Returns the of the project's user languages file. +sub UserLanguagesFileStatus + { return $userLanguagesFileStatus; }; + +# Function: SettingsFile +# Returns the full path to the project's settings file. +sub SettingsFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDirectory(), 'Settings.txt' ); }; + +# Function: PreviousSettingsFile +# Returns the full path to the project's previous settings file. +sub PreviousSettingsFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDataDirectory(), 'PreviousSettings.nd' ); }; + +# Function: PreviousMenuStateFile +# Returns the full path to the project's previous menu state file. +sub PreviousMenuStateFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDataDirectory(), 'PreviousMenuState.nd' ); }; + +# Function: MenuBackupFile +# Returns the full path to the project's menu backup file, which is used to save the original menu in some situations. +sub MenuBackupFile + { return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDirectory(), 'Menu_Backup.txt' ); }; + + + +############################################################################### +# Group: Source File Functions + + +# Function: FilesToParse +# Returns an existence hashref of the to parse. This is not a copy of the data, so don't change it. +sub FilesToParse + { return \%filesToParse; }; + +# Function: FilesToBuild +# Returns an existence hashref of the to build. This is not a copy of the data, so don't change it. +sub FilesToBuild + { return \%filesToBuild; }; + +# Function: FilesToPurge +# Returns an existence hashref of the that had content last time, but now either don't anymore or were deleted. +# This is not a copy of the data, so don't change it. +sub FilesToPurge + { return \%filesToPurge; }; + +# +# Function: RebuildFile +# +# Adds the file to the list of files to build. This function will automatically filter out files that don't have Natural Docs content and +# files that are part of . If this gets called on a file and that file later gets Natural Docs content, it will be added. +# +# Parameters: +# +# file - The to build or rebuild. +# +sub RebuildFile #(file) + { + my ($self, $file) = @_; + + # We don't want to add it to the build list if it doesn't exist, doesn't have Natural Docs content, or it's going to be purged. + # If it wasn't parsed yet and will later be found to have ND content, it will be added by SetHasContent(). + if (exists $supportedFiles{$file} && !exists $filesToPurge{$file} && $supportedFiles{$file}->HasContent()) + { + $filesToBuild{$file} = 1; + + if (exists $unbuiltFilesWithContent{$file}) + { delete $unbuiltFilesWithContent{$file}; }; + }; + }; + + +# +# Function: ReparseEverything +# +# Adds all supported files to the list of files to parse. This does not necessarily mean these files are going to be rebuilt. +# +sub ReparseEverything + { + my ($self) = @_; + + if (!$reparseEverything) + { + foreach my $file (keys %supportedFiles) + { + $filesToParse{$file} = 1; + }; + + $reparseEverything = 1; + }; + }; + + +# +# Function: RebuildEverything +# +# Adds all supported files to the list of files to build. This does not necessarily mean these files are going to be reparsed. +# +sub RebuildEverything + { + my ($self) = @_; + + foreach my $file (keys %unbuiltFilesWithContent) + { + $filesToBuild{$file} = 1; + }; + + %unbuiltFilesWithContent = ( ); + $rebuildEverything = 1; + + NaturalDocs::SymbolTable->RebuildAllIndexes(); + + if ($menuFileStatus == ::FILE_SAME()) + { $menuFileStatus = ::FILE_CHANGED(); }; + }; + + +# Function: UnbuiltFilesWithContent +# Returns an existence hashref of the that have Natural Docs content but are not part of . This is +# not a copy of the data so don't change it. +sub UnbuiltFilesWithContent + { return \%unbuiltFilesWithContent; }; + +# Function: FilesWithContent +# Returns and existence hashref of the that have Natural Docs content. +sub FilesWithContent + { + # Don't keep this one internally, but there's an easy way to make it. + return { %filesToBuild, %unbuiltFilesWithContent }; + }; + + +# +# Function: HasContent +# +# Returns whether the contains Natural Docs content. +# +sub HasContent #(file) + { + my ($self, $file) = @_; + + if (exists $supportedFiles{$file}) + { return $supportedFiles{$file}->HasContent(); } + else + { return undef; }; + }; + + +# +# Function: SetHasContent +# +# Sets whether the has Natural Docs content or not. +# +sub SetHasContent #(file, hasContent) + { + my ($self, $file, $hasContent) = @_; + + if (exists $supportedFiles{$file} && $supportedFiles{$file}->HasContent() != $hasContent) + { + # If the file now has content... + if ($hasContent) + { + $filesToBuild{$file} = 1; + } + + # If the file's content has been removed... + else + { + delete $filesToBuild{$file}; # may not be there + $filesToPurge{$file} = 1; + }; + + $supportedFiles{$file}->SetHasContent($hasContent); + }; + }; + + +# +# Function: StatusOf +# +# Returns the of the passed . +# +sub StatusOf #(file) + { + my ($self, $file) = @_; + + if (exists $supportedFiles{$file}) + { return $supportedFiles{$file}->Status(); } + else + { return ::FILE_DOESNTEXIST(); }; + }; + + +# +# Function: DefaultMenuTitleOf +# +# Returns the default menu title of the . If one isn't specified, it returns the . +# +sub DefaultMenuTitleOf #(file) + { + my ($self, $file) = @_; + + if (exists $supportedFiles{$file}) + { return $supportedFiles{$file}->DefaultMenuTitle(); } + else + { return $file; }; + }; + + +# +# Function: SetDefaultMenuTitle +# +# Sets the default menu title. +# +sub SetDefaultMenuTitle #(file, menuTitle) + { + my ($self, $file, $menuTitle) = @_; + + if (exists $supportedFiles{$file} && $supportedFiles{$file}->DefaultMenuTitle() ne $menuTitle) + { + $supportedFiles{$file}->SetDefaultMenuTitle($menuTitle); + NaturalDocs::Menu->OnDefaultTitleChange($file); + }; + }; + + +# +# Function: MostUsedLanguage +# +# Returns the name of the most used language in the source trees. Does not include text files. +# +sub MostUsedLanguage + { return $mostUsedLanguage; }; + + + +############################################################################### +# Group: Support Functions + +# +# Function: GetAllSupportedFiles +# +# Gets all the supported files in the passed directory and its subdirectories and puts them into . The only +# attribute that will be set is LastModified()>. Also sets . +# +sub GetAllSupportedFiles + { + my ($self) = @_; + + my @directories = @{NaturalDocs::Settings->InputDirectories()}; + + # Keys are language names, values are counts. + my %languageCounts; + + + # Make an existence hash of excluded directories. + + my %excludedDirectories; + my $excludedDirectoryArrayRef = NaturalDocs::Settings->ExcludedInputDirectories(); + + foreach my $excludedDirectory (@$excludedDirectoryArrayRef) + { + if (NaturalDocs::File->IsCaseSensitive()) + { $excludedDirectories{$excludedDirectory} = 1; } + else + { $excludedDirectories{lc($excludedDirectory)} = 1; }; + }; + + + while (scalar @directories) + { + my $directory = pop @directories; + + opendir DIRECTORYHANDLE, $directory; + my @entries = readdir DIRECTORYHANDLE; + closedir DIRECTORYHANDLE; + + @entries = NaturalDocs::File->NoUpwards(@entries); + + foreach my $entry (@entries) + { + my $fullEntry = NaturalDocs::File->JoinPaths($directory, $entry); + + # If an entry is a directory, recurse. + if (-d $fullEntry) + { + # Join again with the noFile flag set in case the platform handles them differently. + $fullEntry = NaturalDocs::File->JoinPaths($directory, $entry, 1); + + if (NaturalDocs::File->IsCaseSensitive()) + { + if (!exists $excludedDirectories{$fullEntry}) + { push @directories, $fullEntry; }; + } + else + { + if (!exists $excludedDirectories{lc($fullEntry)}) + { push @directories, $fullEntry; }; + }; + } + + # Otherwise add it if it's a supported extension. + else + { + if (my $language = NaturalDocs::Languages->LanguageOf($fullEntry)) + { + $supportedFiles{$fullEntry} = NaturalDocs::Project::File->New(undef, (stat($fullEntry))[9], undef, undef); + $languageCounts{$language->Name()}++; + }; + }; + }; + }; + + + my $topCount = 0; + + while (my ($language, $count) = each %languageCounts) + { + if ($count > $topCount && $language ne 'Text File') + { + $topCount = $count; + $mostUsedLanguage = $language; + }; + }; + }; + + +1; -- cgit 1.4.1