bixbite 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +20 -0
- data/README.markdown +49 -0
- data/VERSION +1 -0
- data/bin/bixbite +73 -0
- data/lib/bixbite.rb +13 -0
- data/lib/bixbite/command.rb +14 -0
- data/lib/bixbite/create.rb +76 -0
- data/template/Rakefile +25 -0
- data/template/assets/bixbite/Rakefile.rb +297 -0
- data/template/assets/naturaldocs/NaturalDocs/Config/Languages.txt +286 -0
- data/template/assets/naturaldocs/NaturalDocs/Config/Topics.txt +382 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/customizinglanguages.html +52 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/customizingtopics.html +74 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting.html +58 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting/reference.html +146 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/documenting/walkthrough.html +180 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/example/Default.css +528 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/example/NaturalDocs.js +204 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/examples.css +90 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/background.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/leftside.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/logo.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbody.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overbodybg.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overleftmargin.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenu.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/overmenubg.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/header/rightside.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/logo.gif +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/about.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/background.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomleft.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/bottomright.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/community.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/customizing.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/images/menu/using.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/index.html +9 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/javascript/BrowserStyles.js +77 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/javascript/PNGHandling.js +72 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/keywords.html +38 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/languages.html +32 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/menu.html +79 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/output.html +84 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/running.html +40 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/styles.css +290 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/styles.html +52 -0
- data/template/assets/naturaldocs/NaturalDocs/Help/troubleshooting.html +18 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/CSSGuide.txt +947 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/File Parsing.txt +83 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/HTMLTestCases.pm +269 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/Languages.txt +107 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/NDMarkup.txt +91 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/Symbol Management.txt +59 -0
- data/template/assets/naturaldocs/NaturalDocs/Info/images/Logo.png +0 -0
- data/template/assets/naturaldocs/NaturalDocs/JavaScript/NaturalDocs.js +836 -0
- data/template/assets/naturaldocs/NaturalDocs/License-GPL.txt +341 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/BinaryFile.pm +294 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder.pm +280 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/Base.pm +348 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/FramedHTML.pm +345 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTML.pm +398 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Builder/HTMLBase.pm +3693 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy.pm +860 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/Class.pm +412 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ClassHierarchy/File.pm +157 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ConfigFile.pm +497 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Constants.pm +165 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/DefineMembers.pm +100 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Error.pm +305 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/File.pm +540 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable.pm +383 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/Reference.pm +44 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ImageReferenceTable/String.pm +110 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages.pm +1475 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/ActionScript.pm +1473 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Ada.pm +38 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced.pm +828 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/Scope.pm +95 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Advanced/ScopeChange.pm +70 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Base.pm +832 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/CSharp.pm +1484 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/PLSQL.pm +319 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Pascal.pm +143 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Perl.pm +1370 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype.pm +92 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Prototype/Parameter.pm +87 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Simple.pm +503 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Languages/Tcl.pm +219 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu.pm +3406 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Menu/Entry.pm +201 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/NDMarkup.pm +76 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser.pm +1331 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/JavaDoc.pm +464 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/Native.pm +1060 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Parser/ParsedTopic.pm +253 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project.pm +1402 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/ImageFile.pm +160 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Project/SourceFile.pm +113 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/ReferenceString.pm +334 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings.pm +1418 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Settings/BuildTarget.pm +66 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB.pm +678 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Extension.pm +84 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/File.pm +129 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/Item.pm +201 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/ItemDefinition.pm +45 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SourceDB/WatchedFileDefinitions.pm +159 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/StatusMessage.pm +102 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolString.pm +212 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable.pm +1984 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/File.pm +186 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/IndexElement.pm +522 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Reference.pm +273 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/ReferenceTarget.pm +97 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/Symbol.pm +428 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/SymbolTable/SymbolDefinition.pm +96 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics.pm +1319 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Topics/Type.pm +151 -0
- data/template/assets/naturaldocs/NaturalDocs/Modules/NaturalDocs/Version.pm +384 -0
- data/template/assets/naturaldocs/NaturalDocs/NaturalDocs +400 -0
- data/template/assets/naturaldocs/NaturalDocs/NaturalDocs.bat +17 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Default.css +767 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Roman.css +765 -0
- data/template/assets/naturaldocs/NaturalDocs/Styles/Small.css +763 -0
- data/template/assets/utilities/pngout +0 -0
- data/template/deploy/public_html/.htaccess +0 -0
- data/template/documentation/js/.htaccess +0 -0
- data/template/src/html/.htaccess +76 -0
- data/template/src/html/css/cmn/global.css +96 -0
- data/template/src/html/css/cmn/ie.css +15 -0
- data/template/src/html/css/cmn/ie6.css +15 -0
- data/template/src/html/images/cmn/.htaccess +0 -0
- data/template/src/html/images/tmp/.htaccess +0 -0
- data/template/src/html/includes/debug.inc +5 -0
- data/template/src/html/includes/footer.inc +52 -0
- data/template/src/html/includes/header.inc +61 -0
- data/template/src/html/includes/html.inc +3 -0
- data/template/src/html/includes/namespace.inc +19 -0
- data/template/src/html/includes/page.inc +151 -0
- data/template/src/html/index.html +35 -0
- data/template/src/html/js/cmn/bootstrap.js +74 -0
- data/template/src/html/js/cmn/global.js +142 -0
- data/template/src/html/js/cmn/lib/LAB.js +348 -0
- data/template/src/html/min/.htaccess +4 -0
- data/template/src/html/min/MinifyCLI.php +19 -0
- data/template/src/html/min/README.txt +132 -0
- data/template/src/html/min/builder/_index.js +242 -0
- data/template/src/html/min/builder/bm.js +36 -0
- data/template/src/html/min/builder/index.php +182 -0
- data/template/src/html/min/builder/ocCheck.php +36 -0
- data/template/src/html/min/builder/rewriteTest.js +1 -0
- data/template/src/html/min/config.php +187 -0
- data/template/src/html/min/groupsConfig.php +34 -0
- data/template/src/html/min/index.php +66 -0
- data/template/src/html/min/lib/FirePHP.php +1370 -0
- data/template/src/html/min/lib/HTTP/ConditionalGet.php +348 -0
- data/template/src/html/min/lib/HTTP/Encoder.php +326 -0
- data/template/src/html/min/lib/JSMin.php +314 -0
- data/template/src/html/min/lib/JSMinPlus.php +1872 -0
- data/template/src/html/min/lib/Minify.php +532 -0
- data/template/src/html/min/lib/Minify/Build.php +103 -0
- data/template/src/html/min/lib/Minify/CSS.php +83 -0
- data/template/src/html/min/lib/Minify/CSS/Compressor.php +250 -0
- data/template/src/html/min/lib/Minify/CSS/UriRewriter.php +270 -0
- data/template/src/html/min/lib/Minify/Cache/APC.php +130 -0
- data/template/src/html/min/lib/Minify/Cache/File.php +125 -0
- data/template/src/html/min/lib/Minify/Cache/Memcache.php +137 -0
- data/template/src/html/min/lib/Minify/ClosureCompiler.php +85 -0
- data/template/src/html/min/lib/Minify/CommentPreserver.php +90 -0
- data/template/src/html/min/lib/Minify/Controller/Base.php +202 -0
- data/template/src/html/min/lib/Minify/Controller/Files.php +78 -0
- data/template/src/html/min/lib/Minify/Controller/Groups.php +94 -0
- data/template/src/html/min/lib/Minify/Controller/MinApp.php +132 -0
- data/template/src/html/min/lib/Minify/Controller/Page.php +82 -0
- data/template/src/html/min/lib/Minify/Controller/Version1.php +118 -0
- data/template/src/html/min/lib/Minify/HTML.php +245 -0
- data/template/src/html/min/lib/Minify/ImportProcessor.php +157 -0
- data/template/src/html/min/lib/Minify/Lines.php +131 -0
- data/template/src/html/min/lib/Minify/Logger.php +45 -0
- data/template/src/html/min/lib/Minify/Packer.php +37 -0
- data/template/src/html/min/lib/Minify/Source.php +187 -0
- data/template/src/html/min/lib/Minify/YUICompressor.php +139 -0
- data/template/src/html/min/lib/Solar/Dir.php +199 -0
- data/template/src/html/min/lib/closure-compiler.jar +0 -0
- data/template/src/html/min/lib/yuicompressor-2.4.2.jar +0 -0
- data/template/src/html/min/utils.php +90 -0
- data/template/src/templates/css/template.css +7 -0
- data/template/src/templates/js/template.js +72 -0
- data/template/src/templates/template.html +18 -0
- data/template/src/yaml/config.yml +46 -0
- data/template/src/yaml/deploy.yml +35 -0
- data/test/bixbite_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +278 -0
@@ -0,0 +1,253 @@
|
|
1
|
+
###############################################################################
|
2
|
+
#
|
3
|
+
# Package: NaturalDocs::Parser::ParsedTopic
|
4
|
+
#
|
5
|
+
###############################################################################
|
6
|
+
#
|
7
|
+
# A class for parsed topics of source files. Also encompasses some of the <TopicType>-specific behavior.
|
8
|
+
#
|
9
|
+
###############################################################################
|
10
|
+
|
11
|
+
# This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
|
12
|
+
# Natural Docs is licensed under the GPL
|
13
|
+
|
14
|
+
use strict;
|
15
|
+
use integer;
|
16
|
+
|
17
|
+
package NaturalDocs::Parser::ParsedTopic;
|
18
|
+
|
19
|
+
|
20
|
+
###############################################################################
|
21
|
+
# Group: Implementation
|
22
|
+
|
23
|
+
#
|
24
|
+
# Constants: Members
|
25
|
+
#
|
26
|
+
# The object is a blessed arrayref with the following indexes.
|
27
|
+
#
|
28
|
+
# TYPE - The <TopicType>.
|
29
|
+
# TITLE - The title of the topic.
|
30
|
+
# PACKAGE - The package <SymbolString> the topic appears in, or undef if none.
|
31
|
+
# USING - An arrayref of additional package <SymbolStrings> available to the topic via "using" statements, or undef if
|
32
|
+
# none.
|
33
|
+
# PROTOTYPE - The prototype, if it exists and is applicable.
|
34
|
+
# SUMMARY - The summary, if it exists.
|
35
|
+
# BODY - The body of the topic, formatted in <NDMarkup>. Some topics may not have bodies, and if not, this
|
36
|
+
# will be undef.
|
37
|
+
# LINE_NUMBER - The line number the topic appears at in the file.
|
38
|
+
# IS_LIST - Whether the topic is a list.
|
39
|
+
#
|
40
|
+
use NaturalDocs::DefineMembers 'TYPE', 'TITLE', 'PACKAGE', 'USING', 'PROTOTYPE', 'SUMMARY', 'BODY',
|
41
|
+
'LINE_NUMBER', 'IS_LIST';
|
42
|
+
# DEPENDENCY: New() depends on the order of these constants, and that this class is not inheriting any members.
|
43
|
+
|
44
|
+
|
45
|
+
#
|
46
|
+
# Architecture: Title, Package, and Symbol Behavior
|
47
|
+
#
|
48
|
+
# Title, package, and symbol behavior is a little awkward so it deserves some explanation. Basically you set them according to
|
49
|
+
# certain rules, but you get computed values that try to hide all the different scoping situations.
|
50
|
+
#
|
51
|
+
# Normal Topics:
|
52
|
+
#
|
53
|
+
# Set them to the title and package as they appear. "Function" and "PkgA.PkgB" will return "Function" for the title,
|
54
|
+
# "PkgA.PkgB" for the package, and "PkgA.PkgB.Function" for the symbol.
|
55
|
+
#
|
56
|
+
# In the rare case that a title has a separator symbol it's treated as inadvertant, so "A vs. B" in "PkgA.PkgB" still returns just
|
57
|
+
# "PkgA.PkgB" for the package even though if you got it from the symbol it can be seen as "PkgA.PkgB.A vs".
|
58
|
+
#
|
59
|
+
# Scope Topics:
|
60
|
+
#
|
61
|
+
# Set the title normally and leave the package undef. So "PkgA.PkgB" and undef will return "PkgA.PkgB" for the title as well
|
62
|
+
# as for the package and symbol.
|
63
|
+
#
|
64
|
+
# The only time you should set the package is when you have full language support and they only documented the class with
|
65
|
+
# a partial title. So if you documented "PkgA.PkgB" with just "PkgB", you want to set the package to "PkgA". This
|
66
|
+
# will return "PkgB" as the title for presentation and will return "PkgA.PkgB" for the package and symbol, which is correct.
|
67
|
+
#
|
68
|
+
# Always Global Topics:
|
69
|
+
#
|
70
|
+
# Set the title and package normally, do not set the package to undef. So "Global" and "PkgA.PkgB" will return "Global" as
|
71
|
+
# the title, "PkgA.PkgB" as the package, and "Global" as the symbol.
|
72
|
+
#
|
73
|
+
# Um, yeah...:
|
74
|
+
#
|
75
|
+
# So does this suck? Yes, yes it does. But the suckiness is centralized here instead of having to be handled everywhere these
|
76
|
+
# issues come into play. Just realize there are a certain set of rules to follow when you *set* these variables, and the results
|
77
|
+
# you see when you *get* them are computed rather than literal.
|
78
|
+
#
|
79
|
+
|
80
|
+
|
81
|
+
###############################################################################
|
82
|
+
# Group: Functions
|
83
|
+
|
84
|
+
#
|
85
|
+
# Function: New
|
86
|
+
#
|
87
|
+
# Creates a new object.
|
88
|
+
#
|
89
|
+
# Parameters:
|
90
|
+
#
|
91
|
+
# type - The <TopicType>.
|
92
|
+
# title - The title of the topic.
|
93
|
+
# package - The package <SymbolString> the topic appears in, or undef if none.
|
94
|
+
# using - An arrayref of additional package <SymbolStrings> available to the topic via "using" statements, or undef if
|
95
|
+
# none.
|
96
|
+
# prototype - The prototype, if it exists and is applicable. Otherwise set to undef.
|
97
|
+
# summary - The summary of the topic, if any.
|
98
|
+
# body - The body of the topic, formatted in <NDMarkup>. May be undef, as some topics may not have bodies.
|
99
|
+
# lineNumber - The line number the topic appears at in the file.
|
100
|
+
# isList - Whether the topic is a list topic or not.
|
101
|
+
#
|
102
|
+
# Returns:
|
103
|
+
#
|
104
|
+
# The new object.
|
105
|
+
#
|
106
|
+
sub New #(type, title, package, using, prototype, summary, body, lineNumber, isList)
|
107
|
+
{
|
108
|
+
# DEPENDENCY: This depends on the order of the parameter list being the same as the constants, and that there are no
|
109
|
+
# members inherited from a base class.
|
110
|
+
|
111
|
+
my $package = shift;
|
112
|
+
|
113
|
+
my $object = [ @_ ];
|
114
|
+
bless $object, $package;
|
115
|
+
|
116
|
+
if (defined $object->[USING])
|
117
|
+
{ $object->[USING] = [ @{$object->[USING]} ]; };
|
118
|
+
|
119
|
+
return $object;
|
120
|
+
};
|
121
|
+
|
122
|
+
|
123
|
+
# Function: Type
|
124
|
+
# Returns the <TopicType>.
|
125
|
+
sub Type
|
126
|
+
{ return $_[0]->[TYPE]; };
|
127
|
+
|
128
|
+
# Function: SetType
|
129
|
+
# Replaces the <TopicType>.
|
130
|
+
sub SetType #(type)
|
131
|
+
{ $_[0]->[TYPE] = $_[1]; };
|
132
|
+
|
133
|
+
# Function: IsList
|
134
|
+
# Returns whether the topic is a list.
|
135
|
+
sub IsList
|
136
|
+
{ return $_[0]->[IS_LIST]; };
|
137
|
+
|
138
|
+
# Function: SetIsList
|
139
|
+
# Sets whether the topic is a list.
|
140
|
+
sub SetIsList
|
141
|
+
{ $_[0]->[IS_LIST] = $_[1]; };
|
142
|
+
|
143
|
+
# Function: Title
|
144
|
+
# Returns the title of the topic.
|
145
|
+
sub Title
|
146
|
+
{ return $_[0]->[TITLE]; };
|
147
|
+
|
148
|
+
# Function: SetTitle
|
149
|
+
# Replaces the topic title.
|
150
|
+
sub SetTitle #(title)
|
151
|
+
{ $_[0]->[TITLE] = $_[1]; };
|
152
|
+
|
153
|
+
#
|
154
|
+
# Function: Symbol
|
155
|
+
#
|
156
|
+
# Returns the <SymbolString> defined by the topic. It is fully resolved and does _not_ need to be joined with <Package()>.
|
157
|
+
#
|
158
|
+
# Type-Specific Behavior:
|
159
|
+
#
|
160
|
+
# - If the <TopicType> is always global, the symbol will be generated from the title only.
|
161
|
+
# - Everything else's symbols will be generated from the title and the package passed to <New()>.
|
162
|
+
#
|
163
|
+
sub Symbol
|
164
|
+
{
|
165
|
+
my ($self) = @_;
|
166
|
+
|
167
|
+
my $titleSymbol = NaturalDocs::SymbolString->FromText($self->[TITLE]);
|
168
|
+
|
169
|
+
if (NaturalDocs::Topics->TypeInfo($self->Type())->Scope() == ::SCOPE_ALWAYS_GLOBAL())
|
170
|
+
{ return $titleSymbol; }
|
171
|
+
else
|
172
|
+
{
|
173
|
+
return NaturalDocs::SymbolString->Join( $self->[PACKAGE], $titleSymbol );
|
174
|
+
};
|
175
|
+
};
|
176
|
+
|
177
|
+
|
178
|
+
#
|
179
|
+
# Function: Package
|
180
|
+
#
|
181
|
+
# Returns the package <SymbolString> that the topic appears in.
|
182
|
+
#
|
183
|
+
# Type-Specific Behavior:
|
184
|
+
#
|
185
|
+
# - If the <TopicType> has scope, the package will be generated from both the title and the package passed to <New()>, not
|
186
|
+
# just the package.
|
187
|
+
# - If the <TopicType> is always global, the package will be the one passed to <New()>, even though it isn't part of it's
|
188
|
+
# <Symbol()>.
|
189
|
+
# - Everything else's package will be what was passed to <New()>, even if the title has separator symbols in it.
|
190
|
+
#
|
191
|
+
sub Package
|
192
|
+
{
|
193
|
+
my ($self) = @_;
|
194
|
+
|
195
|
+
# Headerless topics may not have a type yet.
|
196
|
+
if ($self->Type() && NaturalDocs::Topics->TypeInfo($self->Type())->Scope() == ::SCOPE_START())
|
197
|
+
{ return $self->Symbol(); }
|
198
|
+
else
|
199
|
+
{ return $self->[PACKAGE]; };
|
200
|
+
};
|
201
|
+
|
202
|
+
|
203
|
+
# Function: SetPackage
|
204
|
+
# Replaces the package the topic appears in. This will behave the same way as the package parameter in <New()>. Later calls
|
205
|
+
# to <Package()> will still be generated according to its type-specific behavior.
|
206
|
+
sub SetPackage #(package)
|
207
|
+
{ $_[0]->[PACKAGE] = $_[1]; };
|
208
|
+
|
209
|
+
# Function: Using
|
210
|
+
# Returns an arrayref of additional scope <SymbolStrings> available to the topic via "using" statements, or undef if none.
|
211
|
+
sub Using
|
212
|
+
{ return $_[0]->[USING]; };
|
213
|
+
|
214
|
+
# Function: SetUsing
|
215
|
+
# Replaces the using arrayref of sope <SymbolStrings>.
|
216
|
+
sub SetUsing #(using)
|
217
|
+
{ $_[0]->[USING] = $_[1]; };
|
218
|
+
|
219
|
+
# Function: Prototype
|
220
|
+
# Returns the prototype if one is defined. Will be undef otherwise.
|
221
|
+
sub Prototype
|
222
|
+
{ return $_[0]->[PROTOTYPE]; };
|
223
|
+
|
224
|
+
# Function: SetPrototype
|
225
|
+
# Replaces the function or variable prototype.
|
226
|
+
sub SetPrototype #(prototype)
|
227
|
+
{ $_[0]->[PROTOTYPE] = $_[1]; };
|
228
|
+
|
229
|
+
# Function: Summary
|
230
|
+
# Returns the topic summary, if it exists, formatted in <NDMarkup>.
|
231
|
+
sub Summary
|
232
|
+
{ return $_[0]->[SUMMARY]; };
|
233
|
+
|
234
|
+
# Function: Body
|
235
|
+
# Returns the topic's body, formatted in <NDMarkup>. May be undef.
|
236
|
+
sub Body
|
237
|
+
{ return $_[0]->[BODY]; };
|
238
|
+
|
239
|
+
# Function: SetBody
|
240
|
+
# Replaces the topic's body, formatted in <NDMarkup>. May be undef.
|
241
|
+
sub SetBody #(body)
|
242
|
+
{
|
243
|
+
my ($self, $body) = @_;
|
244
|
+
$self->[BODY] = $body;
|
245
|
+
};
|
246
|
+
|
247
|
+
# Function: LineNumber
|
248
|
+
# Returns the line the topic appears at in the file.
|
249
|
+
sub LineNumber
|
250
|
+
{ return $_[0]->[LINE_NUMBER]; };
|
251
|
+
|
252
|
+
|
253
|
+
1;
|
@@ -0,0 +1,1402 @@
|
|
1
|
+
###############################################################################
|
2
|
+
#
|
3
|
+
# Package: NaturalDocs::Project
|
4
|
+
#
|
5
|
+
###############################################################################
|
6
|
+
#
|
7
|
+
# A package that manages information about the files in the source tree, as well as the list of files that have to be parsed
|
8
|
+
# and built.
|
9
|
+
#
|
10
|
+
# Usage and Dependencies:
|
11
|
+
#
|
12
|
+
# - All the <Config and Data File Functions> are available immediately, except for the status functions.
|
13
|
+
#
|
14
|
+
# - <ReparseEverything()> and <RebuildEverything()> are available immediately, because they may need to be called
|
15
|
+
# after <LoadConfigFileInfo()> but before <LoadSourceFileInfo()>.
|
16
|
+
#
|
17
|
+
# - Prior to <LoadConfigFileInfo()>, <NaturalDocs::Settings> must be initialized.
|
18
|
+
#
|
19
|
+
# - After <LoadConfigFileInfo()>, the status <Config and Data File Functions> are available as well.
|
20
|
+
#
|
21
|
+
# - Prior to <LoadSourceFileInfo()>, <NaturalDocs::Settings> and <NaturalDocs::Languages> must be initialized.
|
22
|
+
#
|
23
|
+
# - After <LoadSourceFileInfo()>, the rest of the <Source File Functions> are available.
|
24
|
+
#
|
25
|
+
###############################################################################
|
26
|
+
|
27
|
+
# This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
|
28
|
+
# Natural Docs is licensed under the GPL
|
29
|
+
|
30
|
+
use NaturalDocs::Project::SourceFile;
|
31
|
+
use NaturalDocs::Project::ImageFile;
|
32
|
+
|
33
|
+
use strict;
|
34
|
+
use integer;
|
35
|
+
|
36
|
+
package NaturalDocs::Project;
|
37
|
+
|
38
|
+
|
39
|
+
###############################################################################
|
40
|
+
# Group: File Handles
|
41
|
+
|
42
|
+
#
|
43
|
+
# handle: FH_FILEINFO
|
44
|
+
#
|
45
|
+
# The file handle for the file information file, <FileInfo.nd>.
|
46
|
+
#
|
47
|
+
|
48
|
+
#
|
49
|
+
# handle: FH_CONFIGFILEINFO
|
50
|
+
#
|
51
|
+
# The file handle for the config file information file, <ConfigFileInfo.nd>.
|
52
|
+
#
|
53
|
+
|
54
|
+
#
|
55
|
+
# handle: FH_IMAGEFILE
|
56
|
+
#
|
57
|
+
# The file handle for determining the dimensions of image files.
|
58
|
+
#
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
###############################################################################
|
63
|
+
# Group: Source File Variables
|
64
|
+
|
65
|
+
|
66
|
+
#
|
67
|
+
# hash: supportedFiles
|
68
|
+
#
|
69
|
+
# A hash of all the supported files in the input directory. The keys are the <FileNames>, and the values are
|
70
|
+
# <NaturalDocs::Project::SourceFile> objects.
|
71
|
+
#
|
72
|
+
my %supportedFiles;
|
73
|
+
|
74
|
+
#
|
75
|
+
# hash: filesToParse
|
76
|
+
#
|
77
|
+
# An existence hash of all the <FileNames> that need to be parsed.
|
78
|
+
#
|
79
|
+
my %filesToParse;
|
80
|
+
|
81
|
+
#
|
82
|
+
# hash: filesToBuild
|
83
|
+
#
|
84
|
+
# An existence hash of all the <FileNames> that need to be built.
|
85
|
+
#
|
86
|
+
my %filesToBuild;
|
87
|
+
|
88
|
+
#
|
89
|
+
# hash: filesToPurge
|
90
|
+
#
|
91
|
+
# An existence hash of the <FileNames> that had Natural Docs content last time, but now either don't exist or no longer have
|
92
|
+
# content.
|
93
|
+
#
|
94
|
+
my %filesToPurge;
|
95
|
+
|
96
|
+
#
|
97
|
+
# hash: unbuiltFilesWithContent
|
98
|
+
#
|
99
|
+
# An existence hash of all the <FileNames> that have Natural Docs content but are not part of <filesToBuild>.
|
100
|
+
#
|
101
|
+
my %unbuiltFilesWithContent;
|
102
|
+
|
103
|
+
|
104
|
+
# bool: reparseEverything
|
105
|
+
# Whether all the source files need to be reparsed.
|
106
|
+
my $reparseEverything;
|
107
|
+
|
108
|
+
# bool: rebuildEverything
|
109
|
+
# Whether all the source files need to be rebuilt.
|
110
|
+
my $rebuildEverything;
|
111
|
+
|
112
|
+
# hash: mostUsedLanguage
|
113
|
+
# The name of the most used language. Doesn't include text files.
|
114
|
+
my $mostUsedLanguage;
|
115
|
+
|
116
|
+
|
117
|
+
|
118
|
+
###############################################################################
|
119
|
+
# Group: Configuration File Variables
|
120
|
+
|
121
|
+
|
122
|
+
#
|
123
|
+
# hash: mainConfigFile
|
124
|
+
#
|
125
|
+
# A hash mapping all the main configuration file names without paths to their <FileStatus>. Prior to <LoadConfigFileInfo()>,
|
126
|
+
# it serves as an existence hashref of the file names.
|
127
|
+
#
|
128
|
+
my %mainConfigFiles = ( 'Topics.txt' => 1, 'Languages.txt' => 1 );
|
129
|
+
|
130
|
+
#
|
131
|
+
# hash: userConfigFiles
|
132
|
+
#
|
133
|
+
# A hash mapping all the user configuration file names without paths to their <FileStatus>. Prior to <LoadConfigFileInfo()>,
|
134
|
+
# it serves as an existence hashref of the file names.
|
135
|
+
#
|
136
|
+
my %userConfigFiles = ( 'Topics.txt' => 1, 'Languages.txt' => 1, 'Menu.txt' => 1 );
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
###############################################################################
|
142
|
+
# Group: Image File Variables
|
143
|
+
|
144
|
+
|
145
|
+
#
|
146
|
+
# hash: imageFileExtensions
|
147
|
+
#
|
148
|
+
# An existence hash of all the file extensions for images. Extensions are in all lowercase.
|
149
|
+
#
|
150
|
+
my %imageFileExtensions = ( 'jpg' => 1, 'jpeg' => 1, 'gif' => 1, 'png' => 1, 'bmp' => 1 );
|
151
|
+
|
152
|
+
|
153
|
+
#
|
154
|
+
# hash: imageFiles
|
155
|
+
#
|
156
|
+
# A hash of all the image files in the project. The keys are the <FileNames> and the values are
|
157
|
+
# <NaturalDocs::Project::ImageFiles>.
|
158
|
+
#
|
159
|
+
my %imageFiles;
|
160
|
+
|
161
|
+
|
162
|
+
#
|
163
|
+
# hash: imageFilesToUpdate
|
164
|
+
#
|
165
|
+
# An existence hash of all the image <FileNames> that need to be updated, either because they changed or they're new to the
|
166
|
+
# project.
|
167
|
+
#
|
168
|
+
my %imageFilesToUpdate;
|
169
|
+
|
170
|
+
|
171
|
+
#
|
172
|
+
# hash: imageFilesToPurge
|
173
|
+
#
|
174
|
+
# An existence hash of all the image <FileNames> that need to be purged, either because the files no longer exist or because
|
175
|
+
# they are no longer used.
|
176
|
+
#
|
177
|
+
my %imageFilesToPurge;
|
178
|
+
|
179
|
+
|
180
|
+
#
|
181
|
+
# hash: insensitiveImageFiles
|
182
|
+
#
|
183
|
+
# A hash that maps all lowercase image <FileNames> to their proper case as it would appear in <imageFiles>. Used for
|
184
|
+
# case insensitivity, obviously.
|
185
|
+
#
|
186
|
+
# You can't just use all lowercase in <imageFiles> because both Linux and HTTP are case sensitive, so the original case must
|
187
|
+
# be preserved. We also want to allow separate entries for files that differ based only on case, so it goes to <imageFiles> first
|
188
|
+
# where they can be distinguished and here only if there's no match. Ties are broken by whichever is lower with cmp, because
|
189
|
+
# it has to resolve consistently on all runs of the program.
|
190
|
+
#
|
191
|
+
my %insensitiveImageFiles;
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
###############################################################################
|
196
|
+
# Group: Files
|
197
|
+
|
198
|
+
|
199
|
+
#
|
200
|
+
# File: FileInfo.nd
|
201
|
+
#
|
202
|
+
# An index of the state of the files as of the last parse. Used to determine if files were added, deleted, or changed.
|
203
|
+
#
|
204
|
+
# Format:
|
205
|
+
#
|
206
|
+
# The format is a text file.
|
207
|
+
#
|
208
|
+
# > [VersionInt: app version]
|
209
|
+
#
|
210
|
+
# The beginning of the file is the <VersionInt> it was generated with.
|
211
|
+
#
|
212
|
+
# > [most used language name]
|
213
|
+
#
|
214
|
+
# Next is the name of the most used language in the source tree. Does not include text files.
|
215
|
+
#
|
216
|
+
# Each following line is
|
217
|
+
#
|
218
|
+
# > [file name] tab [last modification time] tab [has ND content (0 or 1)] tab [default menu title] \n
|
219
|
+
#
|
220
|
+
# Revisions:
|
221
|
+
#
|
222
|
+
# 1.3:
|
223
|
+
#
|
224
|
+
# - The line following the <VersionInt>, which was previously the last modification time of <Menu.txt>, was changed to
|
225
|
+
# the name of the most used language.
|
226
|
+
#
|
227
|
+
# 1.16:
|
228
|
+
#
|
229
|
+
# - File names are now absolute. Prior to 1.16, they were relative to the input directory since only one was allowed.
|
230
|
+
#
|
231
|
+
# 1.14:
|
232
|
+
#
|
233
|
+
# - The file was renamed from NaturalDocs.files to FileInfo.nd and moved into the Data subdirectory.
|
234
|
+
#
|
235
|
+
# 0.95:
|
236
|
+
#
|
237
|
+
# - The file version was changed to match the program version. Prior to 0.95, the version line was 1. Test for "1" instead
|
238
|
+
# of "1.0" to distinguish.
|
239
|
+
#
|
240
|
+
|
241
|
+
|
242
|
+
#
|
243
|
+
# File: ConfigFileInfo.nd
|
244
|
+
#
|
245
|
+
# An index of the state of the config files as of the last parse.
|
246
|
+
#
|
247
|
+
# Format:
|
248
|
+
#
|
249
|
+
# > [BINARY_FORMAT]
|
250
|
+
# > [VersionInt: app version]
|
251
|
+
#
|
252
|
+
# First is the standard <BINARY_FORMAT> <VersionInt> header.
|
253
|
+
#
|
254
|
+
# > [UInt32: last modification time of menu]
|
255
|
+
# > [UInt32: last modification of main topics file]
|
256
|
+
# > [UInt32: last modification of user topics file]
|
257
|
+
# > [UInt32: last modification of main languages file]
|
258
|
+
# > [UInt32: last modification of user languages file]
|
259
|
+
#
|
260
|
+
# Next are the last modification times of various configuration files as UInt32s in the standard Unix format.
|
261
|
+
#
|
262
|
+
#
|
263
|
+
# Revisions:
|
264
|
+
#
|
265
|
+
# 1.3:
|
266
|
+
#
|
267
|
+
# - The file was added to Natural Docs. Previously the last modification of <Menu.txt> was stored in <FileInfo.nd>, and
|
268
|
+
# <Topics.txt> and <Languages.txt> didn't exist.
|
269
|
+
#
|
270
|
+
|
271
|
+
|
272
|
+
#
|
273
|
+
# File: ImageFileInfo.nd
|
274
|
+
#
|
275
|
+
# An index of the state of the image files as of the last parse.
|
276
|
+
#
|
277
|
+
# Format:
|
278
|
+
#
|
279
|
+
# > [Standard Binary Header]
|
280
|
+
#
|
281
|
+
# First is the standard binary file header as defined by <NaturalDocs::BinaryFile>.
|
282
|
+
#
|
283
|
+
# > [AString16: file name or undef]
|
284
|
+
# > [UInt32: last modification time]
|
285
|
+
# > [UInt8: was used]
|
286
|
+
#
|
287
|
+
# This section is repeated until the file name is null. The last modification times are UInt32s in the standard Unix format.
|
288
|
+
#
|
289
|
+
#
|
290
|
+
# Revisions:
|
291
|
+
#
|
292
|
+
# 1.4:
|
293
|
+
#
|
294
|
+
# - The file was added to Natural Docs.
|
295
|
+
#
|
296
|
+
|
297
|
+
|
298
|
+
|
299
|
+
###############################################################################
|
300
|
+
# Group: File Functions
|
301
|
+
|
302
|
+
#
|
303
|
+
# Function: LoadSourceFileInfo
|
304
|
+
#
|
305
|
+
# Loads the project file from disk and compares it against the files in the input directory. Project is loaded from
|
306
|
+
# <FileInfo.nd>. New and changed files will be added to <FilesToParse()>, and if they have content,
|
307
|
+
# <FilesToBuild()>.
|
308
|
+
#
|
309
|
+
# Will call <NaturalDocs::Languages->OnMostUsedLanguageKnown()> if <MostUsedLanguage()> changes.
|
310
|
+
#
|
311
|
+
# Returns:
|
312
|
+
#
|
313
|
+
# Returns whether the project was changed in any way.
|
314
|
+
#
|
315
|
+
sub LoadSourceFileInfo
|
316
|
+
{
|
317
|
+
my ($self) = @_;
|
318
|
+
|
319
|
+
$self->GetAllSupportedFiles();
|
320
|
+
NaturalDocs::Languages->OnMostUsedLanguageKnown();
|
321
|
+
|
322
|
+
my $fileIsOkay;
|
323
|
+
my $version;
|
324
|
+
my $hasChanged;
|
325
|
+
|
326
|
+
if (open(FH_FILEINFO, '<' . $self->DataFile('FileInfo.nd')))
|
327
|
+
{
|
328
|
+
# Check if the file is in the right format.
|
329
|
+
$version = NaturalDocs::Version->FromTextFile(\*FH_FILEINFO);
|
330
|
+
|
331
|
+
# The project file need to be rebuilt for 1.16. The source files need to be reparsed and the output files rebuilt for 1.4.
|
332
|
+
# We'll tolerate the difference between 1.16 and 1.3 in the loader.
|
333
|
+
|
334
|
+
if (NaturalDocs::Version->CheckFileFormat( $version, NaturalDocs::Version->FromString('1.16') ))
|
335
|
+
{
|
336
|
+
$fileIsOkay = 1;
|
337
|
+
|
338
|
+
if (!NaturalDocs::Version->CheckFileFormat( $version, NaturalDocs::Version->FromString('1.4') ))
|
339
|
+
{
|
340
|
+
$reparseEverything = 1;
|
341
|
+
$rebuildEverything = 1;
|
342
|
+
$hasChanged = 1;
|
343
|
+
};
|
344
|
+
}
|
345
|
+
else
|
346
|
+
{
|
347
|
+
close(FH_FILEINFO);
|
348
|
+
$hasChanged = 1;
|
349
|
+
};
|
350
|
+
};
|
351
|
+
|
352
|
+
|
353
|
+
if ($fileIsOkay)
|
354
|
+
{
|
355
|
+
my %indexedFiles;
|
356
|
+
|
357
|
+
|
358
|
+
my $line = <FH_FILEINFO>;
|
359
|
+
::XChomp(\$line);
|
360
|
+
|
361
|
+
# Prior to 1.3 it was the last modification time of Menu.txt, which we ignore and treat as though the most used language
|
362
|
+
# changed. Prior to 1.32 the settings didn't transfer over correctly to Menu.txt so we need to behave that way again.
|
363
|
+
if ($version < NaturalDocs::Version->FromString('1.32') || lc($mostUsedLanguage) ne lc($line))
|
364
|
+
{
|
365
|
+
$reparseEverything = 1;
|
366
|
+
NaturalDocs::SymbolTable->RebuildAllIndexes();
|
367
|
+
};
|
368
|
+
|
369
|
+
|
370
|
+
# Parse the rest of the file.
|
371
|
+
|
372
|
+
while ($line = <FH_FILEINFO>)
|
373
|
+
{
|
374
|
+
::XChomp(\$line);
|
375
|
+
my ($file, $modification, $hasContent, $menuTitle) = split(/\t/, $line, 4);
|
376
|
+
|
377
|
+
# If the file no longer exists...
|
378
|
+
if (!exists $supportedFiles{$file})
|
379
|
+
{
|
380
|
+
if ($hasContent)
|
381
|
+
{ $filesToPurge{$file} = 1; };
|
382
|
+
|
383
|
+
$hasChanged = 1;
|
384
|
+
}
|
385
|
+
|
386
|
+
# If the file still exists...
|
387
|
+
else
|
388
|
+
{
|
389
|
+
$indexedFiles{$file} = 1;
|
390
|
+
|
391
|
+
# If the file changed...
|
392
|
+
if ($supportedFiles{$file}->LastModified() != $modification)
|
393
|
+
{
|
394
|
+
$supportedFiles{$file}->SetStatus(::FILE_CHANGED());
|
395
|
+
$filesToParse{$file} = 1;
|
396
|
+
|
397
|
+
# If the file loses its content, this will be removed by SetHasContent().
|
398
|
+
if ($hasContent)
|
399
|
+
{ $filesToBuild{$file} = 1; };
|
400
|
+
|
401
|
+
$hasChanged = 1;
|
402
|
+
}
|
403
|
+
|
404
|
+
# If the file has not changed...
|
405
|
+
else
|
406
|
+
{
|
407
|
+
my $status;
|
408
|
+
|
409
|
+
if ($rebuildEverything && $hasContent)
|
410
|
+
{
|
411
|
+
$status = ::FILE_CHANGED();
|
412
|
+
|
413
|
+
# If the file loses its content, this will be removed by SetHasContent().
|
414
|
+
$filesToBuild{$file} = 1;
|
415
|
+
$hasChanged = 1;
|
416
|
+
}
|
417
|
+
else
|
418
|
+
{
|
419
|
+
$status = ::FILE_SAME();
|
420
|
+
|
421
|
+
if ($hasContent)
|
422
|
+
{ $unbuiltFilesWithContent{$file} = 1; };
|
423
|
+
};
|
424
|
+
|
425
|
+
if ($reparseEverything)
|
426
|
+
{
|
427
|
+
$status = ::FILE_CHANGED();
|
428
|
+
|
429
|
+
$filesToParse{$file} = 1;
|
430
|
+
$hasChanged = 1;
|
431
|
+
};
|
432
|
+
|
433
|
+
$supportedFiles{$file}->SetStatus($status);
|
434
|
+
};
|
435
|
+
|
436
|
+
$supportedFiles{$file}->SetHasContent($hasContent);
|
437
|
+
$supportedFiles{$file}->SetDefaultMenuTitle($menuTitle);
|
438
|
+
};
|
439
|
+
};
|
440
|
+
|
441
|
+
close(FH_FILEINFO);
|
442
|
+
|
443
|
+
|
444
|
+
# Check for added files.
|
445
|
+
|
446
|
+
if (scalar keys %supportedFiles > scalar keys %indexedFiles)
|
447
|
+
{
|
448
|
+
foreach my $file (keys %supportedFiles)
|
449
|
+
{
|
450
|
+
if (!exists $indexedFiles{$file})
|
451
|
+
{
|
452
|
+
$supportedFiles{$file}->SetStatus(::FILE_NEW());
|
453
|
+
$supportedFiles{$file}->SetDefaultMenuTitle($file);
|
454
|
+
$supportedFiles{$file}->SetHasContent(undef);
|
455
|
+
$filesToParse{$file} = 1;
|
456
|
+
# It will be added to filesToBuild if HasContent gets set to true when it's parsed.
|
457
|
+
$hasChanged = 1;
|
458
|
+
};
|
459
|
+
};
|
460
|
+
};
|
461
|
+
}
|
462
|
+
|
463
|
+
# If something's wrong with FileInfo.nd, everything is new.
|
464
|
+
else
|
465
|
+
{
|
466
|
+
foreach my $file (keys %supportedFiles)
|
467
|
+
{
|
468
|
+
$supportedFiles{$file}->SetStatus(::FILE_NEW());
|
469
|
+
$supportedFiles{$file}->SetDefaultMenuTitle($file);
|
470
|
+
$supportedFiles{$file}->SetHasContent(undef);
|
471
|
+
$filesToParse{$file} = 1;
|
472
|
+
# It will be added to filesToBuild if HasContent gets set to true when it's parsed.
|
473
|
+
};
|
474
|
+
|
475
|
+
$hasChanged = 1;
|
476
|
+
};
|
477
|
+
|
478
|
+
|
479
|
+
# There are other side effects, so we need to call this.
|
480
|
+
if ($rebuildEverything)
|
481
|
+
{ $self->RebuildEverything(); };
|
482
|
+
|
483
|
+
|
484
|
+
return $hasChanged;
|
485
|
+
};
|
486
|
+
|
487
|
+
|
488
|
+
#
|
489
|
+
# Function: SaveSourceFileInfo
|
490
|
+
#
|
491
|
+
# Saves the source file info to disk. Everything is saved in <FileInfo.nd>.
|
492
|
+
#
|
493
|
+
sub SaveSourceFileInfo
|
494
|
+
{
|
495
|
+
my ($self) = @_;
|
496
|
+
|
497
|
+
open(FH_FILEINFO, '>' . $self->DataFile('FileInfo.nd'))
|
498
|
+
or die "Couldn't save project file " . $self->DataFile('FileInfo.nd') . "\n";
|
499
|
+
|
500
|
+
NaturalDocs::Version->ToTextFile(\*FH_FILEINFO, NaturalDocs::Settings->AppVersion());
|
501
|
+
|
502
|
+
print FH_FILEINFO $mostUsedLanguage . "\n";
|
503
|
+
|
504
|
+
while (my ($fileName, $file) = each %supportedFiles)
|
505
|
+
{
|
506
|
+
print FH_FILEINFO $fileName . "\t"
|
507
|
+
. $file->LastModified() . "\t"
|
508
|
+
. ($file->HasContent() || '0') . "\t"
|
509
|
+
. $file->DefaultMenuTitle() . "\n";
|
510
|
+
};
|
511
|
+
|
512
|
+
close(FH_FILEINFO);
|
513
|
+
};
|
514
|
+
|
515
|
+
|
516
|
+
#
|
517
|
+
# Function: LoadConfigFileInfo
|
518
|
+
#
|
519
|
+
# Loads the config file info from disk.
|
520
|
+
#
|
521
|
+
sub LoadConfigFileInfo
|
522
|
+
{
|
523
|
+
my ($self) = @_;
|
524
|
+
|
525
|
+
my $fileIsOkay;
|
526
|
+
my $version;
|
527
|
+
my $fileName = NaturalDocs::Project->DataFile('ConfigFileInfo.nd');
|
528
|
+
|
529
|
+
if (open(FH_CONFIGFILEINFO, '<' . $fileName))
|
530
|
+
{
|
531
|
+
# See if it's binary.
|
532
|
+
binmode(FH_CONFIGFILEINFO);
|
533
|
+
|
534
|
+
my $firstChar;
|
535
|
+
read(FH_CONFIGFILEINFO, $firstChar, 1);
|
536
|
+
|
537
|
+
if ($firstChar == ::BINARY_FORMAT())
|
538
|
+
{
|
539
|
+
$version = NaturalDocs::Version->FromBinaryFile(\*FH_CONFIGFILEINFO);
|
540
|
+
|
541
|
+
# It hasn't changed since being introduced.
|
542
|
+
|
543
|
+
if (NaturalDocs::Version->CheckFileFormat($version))
|
544
|
+
{ $fileIsOkay = 1; }
|
545
|
+
else
|
546
|
+
{ close(FH_CONFIGFILEINFO); };
|
547
|
+
}
|
548
|
+
|
549
|
+
else # it's not in binary
|
550
|
+
{ close(FH_CONFIGFILEINFO); };
|
551
|
+
};
|
552
|
+
|
553
|
+
my @configFiles = ( $self->UserConfigFile('Menu.txt'), \$userConfigFiles{'Menu.txt'},
|
554
|
+
$self->MainConfigFile('Topics.txt'), \$mainConfigFiles{'Topics.txt'},
|
555
|
+
$self->UserConfigFile('Topics.txt'), \$userConfigFiles{'Topics.txt'},
|
556
|
+
$self->MainConfigFile('Languages.txt'), \$mainConfigFiles{'Languages.txt'},
|
557
|
+
$self->UserConfigFile('Languages.txt'), \$userConfigFiles{'Languages.txt'} );
|
558
|
+
|
559
|
+
if ($fileIsOkay)
|
560
|
+
{
|
561
|
+
my $raw;
|
562
|
+
|
563
|
+
read(FH_CONFIGFILEINFO, $raw, 20);
|
564
|
+
my @configFileDates = unpack('NNNNN', $raw);
|
565
|
+
|
566
|
+
while (scalar @configFiles)
|
567
|
+
{
|
568
|
+
my $file = shift @configFiles;
|
569
|
+
my $fileStatus = shift @configFiles;
|
570
|
+
my $fileDate = shift @configFileDates;
|
571
|
+
|
572
|
+
if (-e $file)
|
573
|
+
{
|
574
|
+
if ($fileDate == (stat($file))[9])
|
575
|
+
{ $$fileStatus = ::FILE_SAME(); }
|
576
|
+
else
|
577
|
+
{ $$fileStatus = ::FILE_CHANGED(); };
|
578
|
+
}
|
579
|
+
else
|
580
|
+
{ $$fileStatus = ::FILE_DOESNTEXIST(); };
|
581
|
+
};
|
582
|
+
|
583
|
+
close(FH_CONFIGFILEINFO);
|
584
|
+
}
|
585
|
+
else # !$fileIsOkay
|
586
|
+
{
|
587
|
+
while (scalar @configFiles)
|
588
|
+
{
|
589
|
+
my $file = shift @configFiles;
|
590
|
+
my $fileStatus = shift @configFiles;
|
591
|
+
|
592
|
+
if (-e $file)
|
593
|
+
{ $$fileStatus = ::FILE_CHANGED(); }
|
594
|
+
else
|
595
|
+
{ $$fileStatus = ::FILE_DOESNTEXIST(); };
|
596
|
+
};
|
597
|
+
};
|
598
|
+
|
599
|
+
if ($userConfigFiles{'Menu.txt'} == ::FILE_SAME() && $rebuildEverything)
|
600
|
+
{ $userConfigFiles{'Menu.txt'} = ::FILE_CHANGED(); };
|
601
|
+
};
|
602
|
+
|
603
|
+
|
604
|
+
#
|
605
|
+
# Function: SaveConfigFileInfo
|
606
|
+
#
|
607
|
+
# Saves the config file info to disk. You *must* save all other config files first, such as <Menu.txt> and <Topics.txt>.
|
608
|
+
#
|
609
|
+
sub SaveConfigFileInfo
|
610
|
+
{
|
611
|
+
my ($self) = @_;
|
612
|
+
|
613
|
+
open (FH_CONFIGFILEINFO, '>' . NaturalDocs::Project->DataFile('ConfigFileInfo.nd'))
|
614
|
+
or die "Couldn't save " . NaturalDocs::Project->DataFile('ConfigFileInfo.nd') . ".\n";
|
615
|
+
|
616
|
+
binmode(FH_CONFIGFILEINFO);
|
617
|
+
|
618
|
+
print FH_CONFIGFILEINFO '' . ::BINARY_FORMAT();
|
619
|
+
|
620
|
+
NaturalDocs::Version->ToBinaryFile(\*FH_CONFIGFILEINFO, NaturalDocs::Settings->AppVersion());
|
621
|
+
|
622
|
+
print FH_CONFIGFILEINFO pack('NNNNN', (stat($self->UserConfigFile('Menu.txt')))[9],
|
623
|
+
(stat($self->MainConfigFile('Topics.txt')))[9],
|
624
|
+
(stat($self->UserConfigFile('Topics.txt')))[9],
|
625
|
+
(stat($self->MainConfigFile('Languages.txt')))[9],
|
626
|
+
(stat($self->UserConfigFile('Languages.txt')))[9] );
|
627
|
+
|
628
|
+
close(FH_CONFIGFILEINFO);
|
629
|
+
};
|
630
|
+
|
631
|
+
|
632
|
+
#
|
633
|
+
# Function: LoadImageFileInfo
|
634
|
+
#
|
635
|
+
# Loads the image file info from disk.
|
636
|
+
#
|
637
|
+
sub LoadImageFileInfo
|
638
|
+
{
|
639
|
+
my ($self) = @_;
|
640
|
+
|
641
|
+
my $version = NaturalDocs::BinaryFile->OpenForReading( NaturalDocs::Project->DataFile('ImageFileInfo.nd') );
|
642
|
+
my $fileIsOkay;
|
643
|
+
|
644
|
+
if (defined $version)
|
645
|
+
{
|
646
|
+
# It hasn't changed since being introduced.
|
647
|
+
|
648
|
+
if (NaturalDocs::Version->CheckFileFormat($version))
|
649
|
+
{ $fileIsOkay = 1; }
|
650
|
+
else
|
651
|
+
{ NaturalDocs::BinaryFile->Close(); };
|
652
|
+
};
|
653
|
+
|
654
|
+
if ($fileIsOkay)
|
655
|
+
{
|
656
|
+
# [AString16: file name or undef]
|
657
|
+
|
658
|
+
while (my $imageFile = NaturalDocs::BinaryFile->GetAString16())
|
659
|
+
{
|
660
|
+
# [UInt32: last modified]
|
661
|
+
# [UInt8: was used]
|
662
|
+
|
663
|
+
my $lastModified = NaturalDocs::BinaryFile->GetUInt32();
|
664
|
+
my $wasUsed = NaturalDocs::BinaryFile->GetUInt8();
|
665
|
+
|
666
|
+
my $imageFileObject = $imageFiles{$imageFile};
|
667
|
+
|
668
|
+
# If there's an image file in ImageFileInfo.nd that no longer exists...
|
669
|
+
if (!$imageFileObject)
|
670
|
+
{
|
671
|
+
$imageFileObject = NaturalDocs::Project::ImageFile->New($lastModified, ::FILE_DOESNTEXIST(), $wasUsed);
|
672
|
+
$imageFiles{$imageFile} = $imageFileObject;
|
673
|
+
|
674
|
+
if ($wasUsed)
|
675
|
+
{ $imageFilesToPurge{$imageFile} = 1; };
|
676
|
+
}
|
677
|
+
else
|
678
|
+
{
|
679
|
+
$imageFileObject->SetWasUsed($wasUsed);
|
680
|
+
|
681
|
+
# This will be removed if it gets any references.
|
682
|
+
if ($wasUsed)
|
683
|
+
{ $imageFilesToPurge{$imageFile} = 1; };
|
684
|
+
|
685
|
+
if ($imageFileObject->LastModified() == $lastModified && !$rebuildEverything)
|
686
|
+
{ $imageFileObject->SetStatus(::FILE_SAME()); }
|
687
|
+
else
|
688
|
+
{ $imageFileObject->SetStatus(::FILE_CHANGED()); };
|
689
|
+
};
|
690
|
+
};
|
691
|
+
|
692
|
+
NaturalDocs::BinaryFile->Close();
|
693
|
+
}
|
694
|
+
|
695
|
+
else # !$fileIsOkay
|
696
|
+
{
|
697
|
+
$self->RebuildEverything();
|
698
|
+
};
|
699
|
+
};
|
700
|
+
|
701
|
+
|
702
|
+
#
|
703
|
+
# Function: SaveImageFileInfo
|
704
|
+
#
|
705
|
+
# Saves the image file info to disk.
|
706
|
+
#
|
707
|
+
sub SaveImageFileInfo
|
708
|
+
{
|
709
|
+
my $self = shift;
|
710
|
+
|
711
|
+
NaturalDocs::BinaryFile->OpenForWriting( NaturalDocs::Project->DataFile('ImageFileInfo.nd') );
|
712
|
+
|
713
|
+
while (my ($imageFile, $imageFileInfo) = each %imageFiles)
|
714
|
+
{
|
715
|
+
if ($imageFileInfo->Status() != ::FILE_DOESNTEXIST())
|
716
|
+
{
|
717
|
+
# [AString16: file name or undef]
|
718
|
+
# [UInt32: last modification time]
|
719
|
+
# [UInt8: was used]
|
720
|
+
|
721
|
+
NaturalDocs::BinaryFile->WriteAString16($imageFile);
|
722
|
+
NaturalDocs::BinaryFile->WriteUInt32($imageFileInfo->LastModified());
|
723
|
+
NaturalDocs::BinaryFile->WriteUInt8( ($imageFileInfo->ReferenceCount() > 0 ? 1 : 0) );
|
724
|
+
};
|
725
|
+
};
|
726
|
+
|
727
|
+
NaturalDocs::BinaryFile->WriteAString16(undef);
|
728
|
+
NaturalDocs::BinaryFile->Close();
|
729
|
+
};
|
730
|
+
|
731
|
+
|
732
|
+
#
|
733
|
+
# Function: MigrateOldFiles
|
734
|
+
#
|
735
|
+
# If the project uses the old file names used prior to 1.14, it converts them to the new file names.
|
736
|
+
#
|
737
|
+
sub MigrateOldFiles
|
738
|
+
{
|
739
|
+
my ($self) = @_;
|
740
|
+
|
741
|
+
my $projectDirectory = NaturalDocs::Settings->ProjectDirectory();
|
742
|
+
|
743
|
+
# We use the menu file as a test to see if we're using the new format.
|
744
|
+
if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs_Menu.txt'))
|
745
|
+
{
|
746
|
+
# The Data subdirectory would have been created by NaturalDocs::Settings.
|
747
|
+
|
748
|
+
rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs_Menu.txt'), $self->UserConfigFile('Menu.txt') );
|
749
|
+
|
750
|
+
if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.sym'))
|
751
|
+
{ rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.sym'), $self->DataFile('SymbolTable.nd') ); };
|
752
|
+
|
753
|
+
if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.files'))
|
754
|
+
{ rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.files'), $self->DataFile('FileInfo.nd') ); };
|
755
|
+
|
756
|
+
if (-e NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.m'))
|
757
|
+
{ rename( NaturalDocs::File->JoinPaths($projectDirectory, 'NaturalDocs.m'), $self->DataFile('PreviousMenuState.nd') ); };
|
758
|
+
};
|
759
|
+
};
|
760
|
+
|
761
|
+
|
762
|
+
|
763
|
+
###############################################################################
|
764
|
+
# Group: Config and Data File Functions
|
765
|
+
|
766
|
+
|
767
|
+
#
|
768
|
+
# Function: MainConfigFile
|
769
|
+
#
|
770
|
+
# Returns the full path to the passed main configuration file. Pass the file name only.
|
771
|
+
#
|
772
|
+
sub MainConfigFile #(string file)
|
773
|
+
{
|
774
|
+
my ($self, $file) = @_;
|
775
|
+
return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ConfigDirectory(), $file );
|
776
|
+
};
|
777
|
+
|
778
|
+
#
|
779
|
+
# Function: MainConfigFileStatus
|
780
|
+
#
|
781
|
+
# Returns the <FileStatus> of the passed main configuration file. Pass the file name only.
|
782
|
+
#
|
783
|
+
sub MainConfigFileStatus #(string file)
|
784
|
+
{
|
785
|
+
my ($self, $file) = @_;
|
786
|
+
return $mainConfigFiles{$file};
|
787
|
+
};
|
788
|
+
|
789
|
+
#
|
790
|
+
# Function: UserConfigFile
|
791
|
+
#
|
792
|
+
# Returns the full path to the passed user configuration file. Pass the file name only.
|
793
|
+
#
|
794
|
+
sub UserConfigFile #(string file)
|
795
|
+
{
|
796
|
+
my ($self, $file) = @_;
|
797
|
+
return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDirectory(), $file );
|
798
|
+
};
|
799
|
+
|
800
|
+
#
|
801
|
+
# Function: UserConfigFileStatus
|
802
|
+
#
|
803
|
+
# Returns the <FileStatus> of the passed user configuration file. Pass the file name only.
|
804
|
+
#
|
805
|
+
sub UserConfigFileStatus #(string file)
|
806
|
+
{
|
807
|
+
my ($self, $file) = @_;
|
808
|
+
return $userConfigFiles{$file};
|
809
|
+
};
|
810
|
+
|
811
|
+
#
|
812
|
+
# Function: DataFile
|
813
|
+
#
|
814
|
+
# Returns the full path to the passed data file. Pass the file name only.
|
815
|
+
#
|
816
|
+
sub DataFile #(string file)
|
817
|
+
{
|
818
|
+
my ($self, $file) = @_;
|
819
|
+
return NaturalDocs::File->JoinPaths( NaturalDocs::Settings->ProjectDataDirectory(), $file );
|
820
|
+
};
|
821
|
+
|
822
|
+
|
823
|
+
|
824
|
+
|
825
|
+
###############################################################################
|
826
|
+
# Group: Source File Functions
|
827
|
+
|
828
|
+
|
829
|
+
# Function: FilesToParse
|
830
|
+
# Returns an existence hashref of the <FileNames> to parse. This is not a copy of the data, so don't change it.
|
831
|
+
sub FilesToParse
|
832
|
+
{ return \%filesToParse; };
|
833
|
+
|
834
|
+
# Function: FilesToBuild
|
835
|
+
# Returns an existence hashref of the <FileNames> to build. This is not a copy of the data, so don't change it.
|
836
|
+
sub FilesToBuild
|
837
|
+
{ return \%filesToBuild; };
|
838
|
+
|
839
|
+
# Function: FilesToPurge
|
840
|
+
# Returns an existence hashref of the <FileNames> that had content last time, but now either don't anymore or were deleted.
|
841
|
+
# This is not a copy of the data, so don't change it.
|
842
|
+
sub FilesToPurge
|
843
|
+
{ return \%filesToPurge; };
|
844
|
+
|
845
|
+
#
|
846
|
+
# Function: RebuildFile
|
847
|
+
#
|
848
|
+
# 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
|
849
|
+
# files that are part of <FilesToPurge()>. If this gets called on a file and that file later gets Natural Docs content, it will be added.
|
850
|
+
#
|
851
|
+
# Parameters:
|
852
|
+
#
|
853
|
+
# file - The <FileName> to build or rebuild.
|
854
|
+
#
|
855
|
+
sub RebuildFile #(file)
|
856
|
+
{
|
857
|
+
my ($self, $file) = @_;
|
858
|
+
|
859
|
+
# 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.
|
860
|
+
# If it wasn't parsed yet and will later be found to have ND content, it will be added by SetHasContent().
|
861
|
+
if (exists $supportedFiles{$file} && !exists $filesToPurge{$file} && $supportedFiles{$file}->HasContent())
|
862
|
+
{
|
863
|
+
$filesToBuild{$file} = 1;
|
864
|
+
|
865
|
+
if (exists $unbuiltFilesWithContent{$file})
|
866
|
+
{ delete $unbuiltFilesWithContent{$file}; };
|
867
|
+
};
|
868
|
+
};
|
869
|
+
|
870
|
+
|
871
|
+
#
|
872
|
+
# Function: ReparseEverything
|
873
|
+
#
|
874
|
+
# Adds all supported files to the list of files to parse. This does not necessarily mean these files are going to be rebuilt.
|
875
|
+
#
|
876
|
+
sub ReparseEverything
|
877
|
+
{
|
878
|
+
my ($self) = @_;
|
879
|
+
|
880
|
+
if (!$reparseEverything)
|
881
|
+
{
|
882
|
+
foreach my $file (keys %supportedFiles)
|
883
|
+
{
|
884
|
+
$filesToParse{$file} = 1;
|
885
|
+
};
|
886
|
+
|
887
|
+
$reparseEverything = 1;
|
888
|
+
};
|
889
|
+
};
|
890
|
+
|
891
|
+
|
892
|
+
#
|
893
|
+
# Function: RebuildEverything
|
894
|
+
#
|
895
|
+
# Adds all supported files to the list of files to build. This does not necessarily mean these files are going to be reparsed.
|
896
|
+
#
|
897
|
+
sub RebuildEverything
|
898
|
+
{
|
899
|
+
my ($self) = @_;
|
900
|
+
|
901
|
+
foreach my $file (keys %unbuiltFilesWithContent)
|
902
|
+
{
|
903
|
+
$filesToBuild{$file} = 1;
|
904
|
+
};
|
905
|
+
|
906
|
+
%unbuiltFilesWithContent = ( );
|
907
|
+
$rebuildEverything = 1;
|
908
|
+
|
909
|
+
NaturalDocs::SymbolTable->RebuildAllIndexes();
|
910
|
+
|
911
|
+
if ($userConfigFiles{'Menu.txt'} == ::FILE_SAME())
|
912
|
+
{ $userConfigFiles{'Menu.txt'} = ::FILE_CHANGED(); };
|
913
|
+
|
914
|
+
while (my ($imageFile, $imageObject) = each %imageFiles)
|
915
|
+
{
|
916
|
+
if ($imageObject->ReferenceCount())
|
917
|
+
{ $imageFilesToUpdate{$imageFile} = 1; };
|
918
|
+
};
|
919
|
+
};
|
920
|
+
|
921
|
+
|
922
|
+
# Function: UnbuiltFilesWithContent
|
923
|
+
# Returns an existence hashref of the <FileNames> that have Natural Docs content but are not part of <FilesToBuild()>. This is
|
924
|
+
# not a copy of the data so don't change it.
|
925
|
+
sub UnbuiltFilesWithContent
|
926
|
+
{ return \%unbuiltFilesWithContent; };
|
927
|
+
|
928
|
+
# Function: FilesWithContent
|
929
|
+
# Returns and existence hashref of the <FileNames> that have Natural Docs content.
|
930
|
+
sub FilesWithContent
|
931
|
+
{
|
932
|
+
# Don't keep this one internally, but there's an easy way to make it.
|
933
|
+
return { %filesToBuild, %unbuiltFilesWithContent };
|
934
|
+
};
|
935
|
+
|
936
|
+
|
937
|
+
#
|
938
|
+
# Function: HasContent
|
939
|
+
#
|
940
|
+
# Returns whether the <FileName> contains Natural Docs content.
|
941
|
+
#
|
942
|
+
sub HasContent #(file)
|
943
|
+
{
|
944
|
+
my ($self, $file) = @_;
|
945
|
+
|
946
|
+
if (exists $supportedFiles{$file})
|
947
|
+
{ return $supportedFiles{$file}->HasContent(); }
|
948
|
+
else
|
949
|
+
{ return undef; };
|
950
|
+
};
|
951
|
+
|
952
|
+
|
953
|
+
#
|
954
|
+
# Function: SetHasContent
|
955
|
+
#
|
956
|
+
# Sets whether the <FileName> has Natural Docs content or not.
|
957
|
+
#
|
958
|
+
sub SetHasContent #(file, hasContent)
|
959
|
+
{
|
960
|
+
my ($self, $file, $hasContent) = @_;
|
961
|
+
|
962
|
+
if (exists $supportedFiles{$file} && $supportedFiles{$file}->HasContent() != $hasContent)
|
963
|
+
{
|
964
|
+
# If the file now has content...
|
965
|
+
if ($hasContent)
|
966
|
+
{
|
967
|
+
$filesToBuild{$file} = 1;
|
968
|
+
}
|
969
|
+
|
970
|
+
# If the file's content has been removed...
|
971
|
+
else
|
972
|
+
{
|
973
|
+
delete $filesToBuild{$file}; # may not be there
|
974
|
+
$filesToPurge{$file} = 1;
|
975
|
+
};
|
976
|
+
|
977
|
+
$supportedFiles{$file}->SetHasContent($hasContent);
|
978
|
+
};
|
979
|
+
};
|
980
|
+
|
981
|
+
|
982
|
+
#
|
983
|
+
# Function: StatusOf
|
984
|
+
#
|
985
|
+
# Returns the <FileStatus> of the passed <FileName>.
|
986
|
+
#
|
987
|
+
sub StatusOf #(file)
|
988
|
+
{
|
989
|
+
my ($self, $file) = @_;
|
990
|
+
|
991
|
+
if (exists $supportedFiles{$file})
|
992
|
+
{ return $supportedFiles{$file}->Status(); }
|
993
|
+
else
|
994
|
+
{ return ::FILE_DOESNTEXIST(); };
|
995
|
+
};
|
996
|
+
|
997
|
+
|
998
|
+
#
|
999
|
+
# Function: DefaultMenuTitleOf
|
1000
|
+
#
|
1001
|
+
# Returns the default menu title of the <FileName>. If one isn't specified, it returns the <FileName>.
|
1002
|
+
#
|
1003
|
+
sub DefaultMenuTitleOf #(file)
|
1004
|
+
{
|
1005
|
+
my ($self, $file) = @_;
|
1006
|
+
|
1007
|
+
if (exists $supportedFiles{$file})
|
1008
|
+
{ return $supportedFiles{$file}->DefaultMenuTitle(); }
|
1009
|
+
else
|
1010
|
+
{ return $file; };
|
1011
|
+
};
|
1012
|
+
|
1013
|
+
|
1014
|
+
#
|
1015
|
+
# Function: SetDefaultMenuTitle
|
1016
|
+
#
|
1017
|
+
# Sets the <FileName's> default menu title.
|
1018
|
+
#
|
1019
|
+
sub SetDefaultMenuTitle #(file, menuTitle)
|
1020
|
+
{
|
1021
|
+
my ($self, $file, $menuTitle) = @_;
|
1022
|
+
|
1023
|
+
if (exists $supportedFiles{$file} && $supportedFiles{$file}->DefaultMenuTitle() ne $menuTitle)
|
1024
|
+
{
|
1025
|
+
$supportedFiles{$file}->SetDefaultMenuTitle($menuTitle);
|
1026
|
+
NaturalDocs::Menu->OnDefaultTitleChange($file);
|
1027
|
+
};
|
1028
|
+
};
|
1029
|
+
|
1030
|
+
|
1031
|
+
#
|
1032
|
+
# Function: MostUsedLanguage
|
1033
|
+
#
|
1034
|
+
# Returns the name of the most used language in the source trees. Does not include text files.
|
1035
|
+
#
|
1036
|
+
sub MostUsedLanguage
|
1037
|
+
{ return $mostUsedLanguage; };
|
1038
|
+
|
1039
|
+
|
1040
|
+
|
1041
|
+
|
1042
|
+
###############################################################################
|
1043
|
+
# Group: Image File Functions
|
1044
|
+
|
1045
|
+
|
1046
|
+
#
|
1047
|
+
# Function: ImageFileExists
|
1048
|
+
# Returns whether the passed image file exists.
|
1049
|
+
#
|
1050
|
+
sub ImageFileExists #(FileName file) => bool
|
1051
|
+
{
|
1052
|
+
my ($self, $file) = @_;
|
1053
|
+
|
1054
|
+
if (!exists $imageFiles{$file})
|
1055
|
+
{ $file = $insensitiveImageFiles{lc($file)}; };
|
1056
|
+
|
1057
|
+
return (exists $imageFiles{$file} && $imageFiles{$file}->Status() != ::FILE_DOESNTEXIST());
|
1058
|
+
};
|
1059
|
+
|
1060
|
+
|
1061
|
+
#
|
1062
|
+
# Function: ImageFileDimensions
|
1063
|
+
# Returns the dimensions of the passed image file as the array ( width, height ). Returns them both as undef if it cannot be
|
1064
|
+
# determined.
|
1065
|
+
#
|
1066
|
+
sub ImageFileDimensions #(FileName file) => (int, int)
|
1067
|
+
{
|
1068
|
+
my ($self, $file) = @_;
|
1069
|
+
|
1070
|
+
if (!exists $imageFiles{$file})
|
1071
|
+
{ $file = $insensitiveImageFiles{lc($file)}; };
|
1072
|
+
|
1073
|
+
my $object = $imageFiles{$file};
|
1074
|
+
if (!$object)
|
1075
|
+
{ die "Tried to get the dimensions of an image that doesn't exist."; };
|
1076
|
+
|
1077
|
+
if ($object->Width() == -1)
|
1078
|
+
{ $self->DetermineImageDimensions($file); };
|
1079
|
+
|
1080
|
+
return ($object->Width(), $object->Height());
|
1081
|
+
};
|
1082
|
+
|
1083
|
+
|
1084
|
+
#
|
1085
|
+
# Function: ImageFileCapitalization
|
1086
|
+
# Returns the properly capitalized version of the passed image <FileName>. Image file paths are treated as case insensitive
|
1087
|
+
# regardless of whether the underlying operating system is or not, so we have to make sure the final version matches the
|
1088
|
+
# capitalization of the actual file.
|
1089
|
+
#
|
1090
|
+
sub ImageFileCapitalization #(FileName file) => FileName
|
1091
|
+
{
|
1092
|
+
my ($self, $file) = @_;
|
1093
|
+
|
1094
|
+
if (exists $imageFiles{$file})
|
1095
|
+
{ return $file; }
|
1096
|
+
elsif (exists $insensitiveImageFiles{lc($file)})
|
1097
|
+
{ return $insensitiveImageFiles{lc($file)}; }
|
1098
|
+
else
|
1099
|
+
{ die "Tried to get the capitalization of an image file that doesn't exist."; };
|
1100
|
+
};
|
1101
|
+
|
1102
|
+
|
1103
|
+
#
|
1104
|
+
# Function: AddImageFileReference
|
1105
|
+
# Adds a reference to the passed image <FileName>.
|
1106
|
+
#
|
1107
|
+
sub AddImageFileReference #(FileName imageFile)
|
1108
|
+
{
|
1109
|
+
my ($self, $imageFile) = @_;
|
1110
|
+
|
1111
|
+
if (!exists $imageFiles{$imageFile})
|
1112
|
+
{ $imageFile = $insensitiveImageFiles{lc($imageFile)}; };
|
1113
|
+
|
1114
|
+
my $imageFileInfo = $imageFiles{$imageFile};
|
1115
|
+
|
1116
|
+
if ($imageFileInfo == undef || $imageFileInfo->Status() == ::FILE_DOESNTEXIST())
|
1117
|
+
{ die "Tried to add a reference to a non-existant image file."; };
|
1118
|
+
|
1119
|
+
if ($imageFileInfo->AddReference() == 1)
|
1120
|
+
{
|
1121
|
+
delete $imageFilesToPurge{$imageFile};
|
1122
|
+
|
1123
|
+
if (!$imageFileInfo->WasUsed() ||
|
1124
|
+
$imageFileInfo->Status() == ::FILE_NEW() ||
|
1125
|
+
$imageFileInfo->Status() == ::FILE_CHANGED())
|
1126
|
+
{ $imageFilesToUpdate{$imageFile} = 1; };
|
1127
|
+
};
|
1128
|
+
};
|
1129
|
+
|
1130
|
+
|
1131
|
+
#
|
1132
|
+
# Function: DeleteImageFileReference
|
1133
|
+
# Deletes a reference from the passed image <FileName>.
|
1134
|
+
#
|
1135
|
+
sub DeleteImageFileReference #(FileName imageFile)
|
1136
|
+
{
|
1137
|
+
my ($self, $imageFile) = @_;
|
1138
|
+
|
1139
|
+
if (!exists $imageFiles{$imageFile})
|
1140
|
+
{ $imageFile = $insensitiveImageFiles{lc($imageFile)}; };
|
1141
|
+
|
1142
|
+
if (!exists $imageFiles{$imageFile})
|
1143
|
+
{ die "Tried to delete a reference to a non-existant image file."; };
|
1144
|
+
|
1145
|
+
if ($imageFiles{$imageFile}->DeleteReference() == 0)
|
1146
|
+
{
|
1147
|
+
delete $imageFilesToUpdate{$imageFile};
|
1148
|
+
|
1149
|
+
if ($imageFiles{$imageFile}->WasUsed())
|
1150
|
+
{ $imageFilesToPurge{$imageFile} = 1; };
|
1151
|
+
};
|
1152
|
+
};
|
1153
|
+
|
1154
|
+
|
1155
|
+
#
|
1156
|
+
# Function: ImageFilesToUpdate
|
1157
|
+
# Returns an existence hashref of image <FileNames> that need to be updated. *Do not change.*
|
1158
|
+
#
|
1159
|
+
sub ImageFilesToUpdate
|
1160
|
+
{ return \%imageFilesToUpdate; };
|
1161
|
+
|
1162
|
+
|
1163
|
+
#
|
1164
|
+
# Function: ImageFilesToPurge
|
1165
|
+
# Returns an existence hashref of image <FileNames> that need to be updated. *Do not change.*
|
1166
|
+
#
|
1167
|
+
sub ImageFilesToPurge
|
1168
|
+
{ return \%imageFilesToPurge; };
|
1169
|
+
|
1170
|
+
|
1171
|
+
|
1172
|
+
###############################################################################
|
1173
|
+
# Group: Support Functions
|
1174
|
+
|
1175
|
+
#
|
1176
|
+
# Function: GetAllSupportedFiles
|
1177
|
+
#
|
1178
|
+
# Gets all the supported files in the passed directory and its subdirectories and puts them into <supportedFiles>. The only
|
1179
|
+
# attribute that will be set is <NaturalDocs::Project::SourceFile->LastModified()>. Also sets <mostUsedLanguage>.
|
1180
|
+
#
|
1181
|
+
sub GetAllSupportedFiles
|
1182
|
+
{
|
1183
|
+
my ($self) = @_;
|
1184
|
+
|
1185
|
+
my @directories = @{NaturalDocs::Settings->InputDirectories()};
|
1186
|
+
my $isCaseSensitive = NaturalDocs::File->IsCaseSensitive();
|
1187
|
+
|
1188
|
+
# Keys are language names, values are counts.
|
1189
|
+
my %languageCounts;
|
1190
|
+
|
1191
|
+
|
1192
|
+
# Make an existence hash of excluded directories.
|
1193
|
+
|
1194
|
+
my %excludedDirectories;
|
1195
|
+
my $excludedDirectoryArrayRef = NaturalDocs::Settings->ExcludedInputDirectories();
|
1196
|
+
|
1197
|
+
foreach my $excludedDirectory (@$excludedDirectoryArrayRef)
|
1198
|
+
{
|
1199
|
+
if ($isCaseSensitive)
|
1200
|
+
{ $excludedDirectories{$excludedDirectory} = 1; }
|
1201
|
+
else
|
1202
|
+
{ $excludedDirectories{lc($excludedDirectory)} = 1; };
|
1203
|
+
};
|
1204
|
+
|
1205
|
+
|
1206
|
+
my $imagesOnly;
|
1207
|
+
my $language;
|
1208
|
+
|
1209
|
+
while (scalar @directories)
|
1210
|
+
{
|
1211
|
+
my $directory = pop @directories;
|
1212
|
+
|
1213
|
+
opendir DIRECTORYHANDLE, $directory;
|
1214
|
+
my @entries = readdir DIRECTORYHANDLE;
|
1215
|
+
closedir DIRECTORYHANDLE;
|
1216
|
+
|
1217
|
+
@entries = NaturalDocs::File->NoUpwards(@entries);
|
1218
|
+
|
1219
|
+
foreach my $entry (@entries)
|
1220
|
+
{
|
1221
|
+
my $fullEntry = NaturalDocs::File->JoinPaths($directory, $entry);
|
1222
|
+
|
1223
|
+
# If an entry is a directory, recurse.
|
1224
|
+
if (-d $fullEntry)
|
1225
|
+
{
|
1226
|
+
# Join again with the noFile flag set in case the platform handles them differently.
|
1227
|
+
$fullEntry = NaturalDocs::File->JoinPaths($directory, $entry, 1);
|
1228
|
+
|
1229
|
+
if ($isCaseSensitive)
|
1230
|
+
{
|
1231
|
+
if (!exists $excludedDirectories{$fullEntry})
|
1232
|
+
{ push @directories, $fullEntry; };
|
1233
|
+
}
|
1234
|
+
else
|
1235
|
+
{
|
1236
|
+
if (!exists $excludedDirectories{lc($fullEntry)})
|
1237
|
+
{ push @directories, $fullEntry; };
|
1238
|
+
};
|
1239
|
+
}
|
1240
|
+
|
1241
|
+
# Otherwise add it if it's a supported extension.
|
1242
|
+
else
|
1243
|
+
{
|
1244
|
+
my $extension = NaturalDocs::File->ExtensionOf($entry);
|
1245
|
+
|
1246
|
+
if (exists $imageFileExtensions{lc($extension)})
|
1247
|
+
{
|
1248
|
+
my $fileObject = NaturalDocs::Project::ImageFile->New( (stat($fullEntry))[9], ::FILE_NEW(), 0 );
|
1249
|
+
$imageFiles{$fullEntry} = $fileObject;
|
1250
|
+
|
1251
|
+
my $lcFullEntry = lc($fullEntry);
|
1252
|
+
|
1253
|
+
if (!exists $insensitiveImageFiles{$lcFullEntry} ||
|
1254
|
+
($fullEntry cmp $insensitiveImageFiles{$lcFullEntry}) < 0)
|
1255
|
+
{
|
1256
|
+
$insensitiveImageFiles{$lcFullEntry} = $fullEntry;
|
1257
|
+
};
|
1258
|
+
}
|
1259
|
+
elsif (!$imagesOnly && ($language = NaturalDocs::Languages->LanguageOf($fullEntry)) )
|
1260
|
+
{
|
1261
|
+
my $fileObject = NaturalDocs::Project::SourceFile->New();
|
1262
|
+
$fileObject->SetLastModified(( stat($fullEntry))[9] );
|
1263
|
+
$supportedFiles{$fullEntry} = $fileObject;
|
1264
|
+
|
1265
|
+
$languageCounts{$language->Name()}++;
|
1266
|
+
};
|
1267
|
+
};
|
1268
|
+
};
|
1269
|
+
|
1270
|
+
|
1271
|
+
# After we run out of source directories, add the image directories.
|
1272
|
+
|
1273
|
+
if (scalar @directories == 0 && !$imagesOnly)
|
1274
|
+
{
|
1275
|
+
$imagesOnly = 1;
|
1276
|
+
@directories = @{NaturalDocs::Settings->ImageDirectories()};
|
1277
|
+
};
|
1278
|
+
};
|
1279
|
+
|
1280
|
+
|
1281
|
+
my $topCount = 0;
|
1282
|
+
|
1283
|
+
while (my ($language, $count) = each %languageCounts)
|
1284
|
+
{
|
1285
|
+
if ($count > $topCount && $language ne 'Text File')
|
1286
|
+
{
|
1287
|
+
$topCount = $count;
|
1288
|
+
$mostUsedLanguage = $language;
|
1289
|
+
};
|
1290
|
+
};
|
1291
|
+
};
|
1292
|
+
|
1293
|
+
|
1294
|
+
#
|
1295
|
+
# Function: DetermineImageDimensions
|
1296
|
+
#
|
1297
|
+
# Attempts to determine the dimensions of the passed image and apply them to their object in <imageFiles>. Will set them to
|
1298
|
+
# undef if they can't be determined.
|
1299
|
+
#
|
1300
|
+
sub DetermineImageDimensions #(FileName imageFile)
|
1301
|
+
{
|
1302
|
+
my ($self, $imageFile) = @_;
|
1303
|
+
|
1304
|
+
my $imageFileObject = $imageFiles{$imageFile};
|
1305
|
+
if (!defined $imageFileObject)
|
1306
|
+
{ die "Tried to determine image dimensions of a file with no object."; };
|
1307
|
+
|
1308
|
+
my $extension = lc( NaturalDocs::File->ExtensionOf($imageFile) );
|
1309
|
+
my ($width, $height);
|
1310
|
+
|
1311
|
+
if ($imageFileExtensions{$extension})
|
1312
|
+
{
|
1313
|
+
open(FH_IMAGEFILE, '<' . $imageFile)
|
1314
|
+
or die 'Could not open ' . $imageFile . "\n";
|
1315
|
+
binmode(FH_IMAGEFILE);
|
1316
|
+
|
1317
|
+
my $raw;
|
1318
|
+
|
1319
|
+
if ($extension eq 'gif')
|
1320
|
+
{
|
1321
|
+
read(FH_IMAGEFILE, $raw, 6);
|
1322
|
+
|
1323
|
+
if ($raw eq 'GIF87a' || $raw eq 'GIF89a')
|
1324
|
+
{
|
1325
|
+
read(FH_IMAGEFILE, $raw, 4);
|
1326
|
+
($width, $height) = unpack('vv', $raw);
|
1327
|
+
};
|
1328
|
+
}
|
1329
|
+
|
1330
|
+
elsif ($extension eq 'png')
|
1331
|
+
{
|
1332
|
+
read(FH_IMAGEFILE, $raw, 8);
|
1333
|
+
|
1334
|
+
if ($raw eq "\x89PNG\x0D\x0A\x1A\x0A")
|
1335
|
+
{
|
1336
|
+
seek(FH_IMAGEFILE, 4, 1);
|
1337
|
+
read(FH_IMAGEFILE, $raw, 4);
|
1338
|
+
|
1339
|
+
if ($raw eq 'IHDR')
|
1340
|
+
{
|
1341
|
+
read(FH_IMAGEFILE, $raw, 8);
|
1342
|
+
($width, $height) = unpack('NN', $raw);
|
1343
|
+
};
|
1344
|
+
};
|
1345
|
+
}
|
1346
|
+
|
1347
|
+
elsif ($extension eq 'bmp')
|
1348
|
+
{
|
1349
|
+
read(FH_IMAGEFILE, $raw, 2);
|
1350
|
+
|
1351
|
+
if ($raw eq 'BM')
|
1352
|
+
{
|
1353
|
+
seek(FH_IMAGEFILE, 16, 1);
|
1354
|
+
read(FH_IMAGEFILE, $raw, 8);
|
1355
|
+
|
1356
|
+
($width, $height) = unpack('VV', $raw);
|
1357
|
+
};
|
1358
|
+
}
|
1359
|
+
|
1360
|
+
elsif ($extension eq 'jpg' || $extension eq 'jpeg')
|
1361
|
+
{
|
1362
|
+
read(FH_IMAGEFILE, $raw, 2);
|
1363
|
+
my $isOkay = ($raw eq "\xFF\xD8");
|
1364
|
+
|
1365
|
+
while ($isOkay)
|
1366
|
+
{
|
1367
|
+
read(FH_IMAGEFILE, $raw, 4);
|
1368
|
+
my ($marker, $code, $length) = unpack('CCn', $raw);
|
1369
|
+
|
1370
|
+
$isOkay = ($marker eq 0xFF);
|
1371
|
+
|
1372
|
+
if ($isOkay)
|
1373
|
+
{
|
1374
|
+
if ($code >= 0xC0 && $code <= 0xC3)
|
1375
|
+
{
|
1376
|
+
read(FH_IMAGEFILE, $raw, 5);
|
1377
|
+
($height, $width) = unpack('xnn', $raw);
|
1378
|
+
last;
|
1379
|
+
}
|
1380
|
+
|
1381
|
+
else
|
1382
|
+
{
|
1383
|
+
$isOkay = seek(FH_IMAGEFILE, $length - 2, 1);
|
1384
|
+
};
|
1385
|
+
};
|
1386
|
+
};
|
1387
|
+
};
|
1388
|
+
|
1389
|
+
close(FH_IMAGEFILE);
|
1390
|
+
};
|
1391
|
+
|
1392
|
+
|
1393
|
+
# Sanity check the values. Although images can theoretically be bigger than 5000, most won't. The worst that happens in this
|
1394
|
+
# case is just that they don't get length and width values in the output anyway.
|
1395
|
+
if ($width > 0 && $width < 5000 && $height > 0 && $height < 5000)
|
1396
|
+
{ $imageFileObject->SetDimensions($width, $height); }
|
1397
|
+
else
|
1398
|
+
{ $imageFileObject->SetDimensions(undef, undef); };
|
1399
|
+
};
|
1400
|
+
|
1401
|
+
|
1402
|
+
1;
|