rant 0.4.4 → 0.4.6

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.
Files changed (89) hide show
  1. data/NEWS +38 -0
  2. data/README +4 -2
  3. data/Rantfile +50 -12
  4. data/doc/examples/c_cpp/c++/problem_1_1/another_test.cpp +6 -0
  5. data/doc/examples/c_cpp/c++/problem_1_1/another_test.h +5 -0
  6. data/doc/examples/c_cpp/c++/problem_1_1/main.cpp +12 -0
  7. data/doc/examples/c_cpp/c++/problem_1_1/test.cpp +6 -0
  8. data/doc/examples/c_cpp/c++/problem_1_1/test.h +5 -0
  9. data/doc/examples/c_cpp/c++/template.rf +15 -0
  10. data/doc/examples/c_cpp/c/problem_1_1/another_test.c +6 -0
  11. data/doc/examples/c_cpp/c/problem_1_1/another_test.h +7 -0
  12. data/doc/examples/c_cpp/c/problem_1_1/main.c +12 -0
  13. data/doc/examples/c_cpp/c/problem_1_1/test.c +6 -0
  14. data/doc/examples/c_cpp/c/problem_1_1/test.h +7 -0
  15. data/doc/examples/c_cpp/c/template.rf +15 -0
  16. data/doc/examples/c_cpp/root.rant +46 -0
  17. data/doc/homepage/index.html +115 -0
  18. data/doc/homepage/rant_home.css +98 -0
  19. data/doc/rant.1 +129 -0
  20. data/doc/rant.rdoc +5 -6
  21. data/doc/rantfile.rdoc +55 -32
  22. data/doc/subdirs.rdoc +147 -0
  23. data/lib/rant.rb +47 -49
  24. data/lib/rant/coregen.rb +20 -20
  25. data/lib/rant/import.rb +63 -11
  26. data/lib/rant/import/archive.rb +47 -15
  27. data/lib/rant/import/archive/tgz.rb +1 -1
  28. data/lib/rant/import/autoclean.rb +28 -26
  29. data/lib/rant/import/c/dependencies.rb +1 -1
  30. data/lib/rant/import/directedrule.rb +1 -4
  31. data/lib/rant/import/metadata.rb +30 -7
  32. data/lib/rant/import/nodes/default.rb +67 -13
  33. data/lib/rant/import/rubypackage.rb +1 -1
  34. data/lib/rant/import/rubytest.rb +25 -19
  35. data/lib/rant/import/signedfile.rb +14 -8
  36. data/lib/rant/import/sys/more.rb +22 -0
  37. data/lib/rant/import/sys/tgz.rb +43 -0
  38. data/lib/rant/import/sys/zip.rb +42 -0
  39. data/lib/rant/node.rb +19 -13
  40. data/lib/rant/plugin/configure.rb +1 -1
  41. data/lib/rant/progress.rb +33 -0
  42. data/lib/rant/rantenv.rb +7 -7
  43. data/lib/rant/rantlib.rb +246 -256
  44. data/lib/rant/rantsys.rb +61 -22
  45. data/lib/rant/rantvar.rb +7 -9
  46. data/misc/TODO +18 -0
  47. data/misc/devel-notes +4 -1
  48. data/test/Rantfile +17 -3
  49. data/test/deprecated/README +6 -0
  50. data/test/deprecated/test_0_4_8.rb +41 -0
  51. data/test/deprecated/test_0_5_2.rb +33 -0
  52. data/test/import/md5/root.rant +9 -0
  53. data/test/import/md5/test_md5.rb +45 -0
  54. data/test/import/metadata/Rantfile +2 -2
  55. data/test/import/metadata/test_metadata.rb +2 -2
  56. data/test/import/package/test_package.rb +40 -1
  57. data/test/import/signedfile/sub1/Rantfile +1 -1
  58. data/test/import/sys/data/pkg.tgz +0 -0
  59. data/test/import/sys/data/pkg.zip +0 -0
  60. data/test/import/sys/data/pkg/bin/test +0 -0
  61. data/test/import/sys/data/pkg/bin/test.o +0 -0
  62. data/test/import/sys/data/pkg/test.c +6 -0
  63. data/test/import/sys/data/pkg/test.h +7 -0
  64. data/test/import/sys/data/pkg2.zip +0 -0
  65. data/test/import/sys/test_tgz.rb +38 -0
  66. data/test/import/sys/test_zip.rb +68 -0
  67. data/test/import/sys/tgz.rf +6 -0
  68. data/test/import/sys/zip.rf +15 -0
  69. data/test/project2/{rantfile.rb → root.rant} +0 -0
  70. data/test/project2/test_project.rb +3 -8
  71. data/test/project_rb1/{rantfile.rb → rantfile} +1 -1
  72. data/test/project_rb1/test_project_rb1.rb +3 -5
  73. data/test/rant-import/test_rant-import.rb +22 -10
  74. data/test/subdirs/sub1/Rantfile +1 -1
  75. data/test/subdirs/sub2/{rantfile.rb → rantfile} +0 -0
  76. data/test/subdirs/sub2/sub/rantfile +1 -1
  77. data/test/subdirs2/root.rant +36 -0
  78. data/test/subdirs2/sub00/sub.rant +8 -0
  79. data/test/subdirs2/sub1/sub.rant +13 -0
  80. data/test/subdirs2/test_subdirs2.rb +239 -0
  81. data/test/test_examples.rb +91 -0
  82. data/test/test_filetask.rb +51 -11
  83. data/test/test_rant_interface.rb +24 -0
  84. data/test/test_rantfile_api.rb +54 -2
  85. data/test/test_sourcenode.rb +30 -0
  86. data/test/test_sys.rb +143 -15
  87. data/test/test_task.rb +16 -22
  88. data/test/tutil.rb +22 -38
  89. metadata +67 -9
data/NEWS CHANGED
@@ -1,6 +1,44 @@
1
1
 
2
2
  = Rant NEWS
3
3
 
4
+ == Rant 0.4.6
5
+
6
+ Incompatible changes:
7
+ * *Important*: The notation <tt>"#foo"</tt> to reference a task
8
+ defined in the project's root directory changed to <tt>"@foo"</tt>.
9
+ * Previous Rant versions loaded both, +Rantfile+ and
10
+ <tt>Rantfile.rb</tt>, if present. This version will only load one of
11
+ them (preferably +Rantfile+).
12
+ * +RubyTest+ tasks no longer honour TESTOPTS variable.
13
+
14
+ Deprecated:
15
+ * The filenames <tt>Rantfile.rb</tt> and <tt>rantfile.rb</tt> are
16
+ deprecated for rantfiles and won't be recognized by future Rant
17
+ versions. Use +Rantfile+, +rantfile+ or <tt>root.rant</tt> instead.
18
+
19
+ Fixes and minor improvements:
20
+ * Fix an issue where a file was unnecessary rebuilt when rant was
21
+ started from different directories, the file task was created from a
22
+ rule and md5 signatures were used.
23
+ * Concise output from Package::Tgz and Package::Zip tasks.
24
+ * A manpage will be installed on Linux/Unix systems by the install.rb
25
+ script.
26
+ * A fix for a FileUtils::Verbose bug in Ruby 1.8.3 which affects some
27
+ <tt>sys</tt> methods.
28
+
29
+ New features:
30
+ * The --cd-parent (-c) option to search for an Rantfile in parent
31
+ directories.
32
+ * The --look-up (-u) option to search for the root Rantfile in parent
33
+ directories.
34
+ * Recognition of rantfiles with the names <tt>root.rant</tt> and
35
+ <tt>sub.rant</tt>, where a <tt>sub.rant</tt> file is meant for a
36
+ project subdirectory and is treated special.
37
+ Read doc/subdirs.rdoc[link:files/doc/subdirs_rdoc.html]
38
+ * The +sys+ and <tt>sys.ruby</tt> methods take an optional block for
39
+ custom process exit status handling (per default, Rant aborts if a
40
+ subprocess started with +sys+ exits with another status than 0).
41
+
4
42
  == Rant 0.4.4
5
43
 
6
44
  Besides internal changes, this release is backwards compatible to
data/README CHANGED
@@ -41,7 +41,7 @@ Running rant in the directory of this file:
41
41
  will ensure that the "data" file in the "backup" directory is up to
42
42
  date.
43
43
 
44
- This document was written for version 0.4.4 of Rant. Most things
44
+ This document was written for version 0.4.6 of Rant. Most things
45
45
  described here will work for older/newer versions of Rant, but look at
46
46
  the README file in the Rant distribution you've installed for exact
47
47
  documentation of your Rant version.
@@ -81,6 +81,8 @@ Using MD5 checksums instead of file modification times::
81
81
  read doc/md5.rdoc[link:files/doc/md5_rdoc.html]
82
82
  Compiling C/C++::
83
83
  read doc/c.rdoc[link:files/doc/c_rdoc.html]
84
+ Buildfiles in subdirectories::
85
+ read doc/subdirs.rdoc[link:files/doc/subdirs_rdoc.html]
84
86
  Using the Configure plugin::
85
87
  read doc/configure.rdoc[link:files/doc/configure_rdoc.html]
86
88
  Compiling C#::
@@ -212,7 +214,7 @@ Rant was tested on:
212
214
  Linux 1.8.0
213
215
  1.8.1
214
216
  1.8.2
215
- 1.8.3 preview 1
217
+ 1.8.3
216
218
  1.9
217
219
  MacOS X 1.8.2
218
220
  Windows XP 1.8.2 (OneClick Installer)
data/Rantfile CHANGED
@@ -2,20 +2,24 @@
2
2
  # Rantfile for Rant :)
3
3
 
4
4
  import "md5"
5
- import %w(rubytest rubydoc rubypackage autoclean win32/rubycmdwrapper)
5
+ import %w(rubytest rubydoc rubypackage autoclean win32/rubycmdwrapper sys/more)
6
6
 
7
7
  task :default => :test
8
8
 
9
9
  dist_files = sys["{bin,lib,test,doc,misc}/**/*"]
10
10
  dist_files.shun("html", "coverage")
11
11
  dist_files += sys["*"].no_dir.exclude("InstalledFiles", "Session.vim")
12
+ dist_files.exclude("bench-*")
13
+ hp_files = sys["doc/homepage/*"]
14
+ extra_rdoc_files = sys["**/README", "NEWS", "doc/**/*.rdoc"]
15
+ extra_rdoc_files.no_dir("pkg").no_dir("test")
12
16
 
13
17
  # remove when compiler stuff is getting useful...
14
18
  dist_files.exclude "lib/rant/compiler*", "lib/rant/import/c/program.rb"
15
19
 
16
20
  rdoc_opts = %w(-S -c UTF-8 --title Rant --main README)
17
21
 
18
- gen RubyPackage, "rant" do |t|
22
+ gen RubyPackage, "rant#{var :pkg_ext}" do |t|
19
23
  t.version = `#{Env::RUBY} run_rant --version`.split[1]
20
24
  t.summary = "Rant is a Ruby based build tool."
21
25
  t.files = dist_files
@@ -25,7 +29,7 @@ gen RubyPackage, "rant" do |t|
25
29
  t.email = "langstefan@gmx.at"
26
30
  t.rubyforge_project = "make"
27
31
  t.homepage = "http://make.rubyforge.org"
28
- t.gem_extra_rdoc_files = sys["**/README", "NEWS"].no_dir("pkg").no_dir("test") + sys["doc/**/*.rdoc"]
32
+ t.gem_extra_rdoc_files = extra_rdoc_files
29
33
  t.gem_rdoc_options = rdoc_opts
30
34
  desc "Create packages for distribution."
31
35
  t.package_task
@@ -35,11 +39,35 @@ desc "Generate documentation."
35
39
  gen RubyDoc do |g|
36
40
  g.verbose = true
37
41
  g.dir = "doc/html"
38
- g.files.concat sys["NEWS", "**/README"].no_dir("pkg").no_dir("test")
39
- g.files.concat sys["doc/**/*.rdoc"]
42
+ g.files.concat extra_rdoc_files
40
43
  g.opts = rdoc_opts + %w(-T doc/jamis.rb)
41
44
  end
42
45
 
46
+ html_index = "doc/html/index.html"
47
+ api_index = html_index.sub("index", "api")
48
+
49
+ enhance "doc/html/index.html" do
50
+ sys.rm_f api_index # remove old RDoc index page
51
+ make "hp2doc"
52
+ end
53
+
54
+ task "hp2doc" do
55
+ if test(?f, html_index) && !test(?f, api_index)
56
+ sys.mv html_index, api_index
57
+ end
58
+ sys.cp hp_files, "doc/html"
59
+ end
60
+
61
+ desc "Publish html docs on make.rubyfore.org.",
62
+ "Note: scp will prompt for rubyforge password."
63
+ task "publish-docs" => :doc do
64
+ sys "scp -r doc/html/* langi@rubyforge.org:/var/www/gforge-projects/make/"
65
+ end
66
+
67
+ task "publish-hp" do
68
+ sys "scp -r doc/homepage/* langi@rubyforge.org:/var/www/gforge-projects/make/"
69
+ end
70
+
43
71
  desc "Run basic tests."
44
72
  gen RubyTest do |g|
45
73
  g.libs << "test"
@@ -74,7 +102,7 @@ desc "Run all tests and generate coverage with rcov."
74
102
  task :cov do
75
103
  lp = File.expand_path "lib"
76
104
  sys.cd "test" do
77
- sys %W(rcov -xtutil.rb,*.t,ts_*,tc_*,test_* -I#{lp} ts_all.rb)
105
+ sys %W(rcov -xtutil.rb,ts_*,tc_*,test_* -I#{lp} ts_all.rb)
78
106
  end
79
107
  end
80
108
 
@@ -120,12 +148,6 @@ var[:clean].include %w(
120
148
  InstalledFiles .config bench-rant bench-depsearch test/coverage
121
149
  )
122
150
 
123
- desc "Publish html docs on make.rubyfore.org.",
124
- "Note: scp will prompt for rubyforge password."
125
- task "publish-docs" => :doc do
126
- sys "scp -r doc/html/* langi@rubyforge.org:/var/www/gforge-projects/make/"
127
- end
128
-
129
151
  # Just for quick visual testing of rant...
130
152
  task :please_fail do |t|
131
153
  sys "mix_nix_gibts"
@@ -145,10 +167,26 @@ end
145
167
  desc "Install Rant."
146
168
  task :install do
147
169
  sys.ruby "setup.rb"
170
+ # try to install man page
171
+ man_path = ENV["MANPATH"]
172
+ if man_path
173
+ puts "trying to install rant(1) manpage..."
174
+ require 'rbconfig'
175
+ prefix = Config::CONFIG["prefix"]
176
+ dirs = sys.split_path man_path
177
+ man_dir = dirs.find{|d| d == "#{prefix}/man" } || dirs.first
178
+ sys.install "doc/rant.1", "#{man_dir}/man1", :mode => 0644 if man_dir
179
+ end
148
180
  end
149
181
 
150
182
  if Env.on_windows?
151
183
  enhance :install => (gen Win32::RubyCmdWrapper, sys["bin/*"])
152
184
  end
153
185
 
186
+ task "svn-clean" do
187
+ `svn stat`.split(/\n/).each { |line|
188
+ sys.clean line[7..-1] if line[0] == ??
189
+ }
190
+ end
191
+
154
192
  # vim:ft=ruby
@@ -0,0 +1,6 @@
1
+
2
+ #include "another_test.h"
3
+
4
+ void another_test()
5
+ {
6
+ }
@@ -0,0 +1,5 @@
1
+
2
+ #ifndef ANOTHER_TEST_H
3
+ #define ANOTHER_TEST_H
4
+
5
+ #endif
@@ -0,0 +1,12 @@
1
+
2
+ #include <iostream>
3
+ #include "test.h"
4
+ #include "another_test.h"
5
+
6
+ using namespace std;
7
+
8
+ int main(char argc, char** argv)
9
+ {
10
+ cout << "Hello, world!" << endl;
11
+ return 0;
12
+ }
@@ -0,0 +1,6 @@
1
+
2
+ #include "test.h"
3
+
4
+ void test()
5
+ {
6
+ }
@@ -0,0 +1,5 @@
1
+
2
+ #ifndef TEST_H
3
+ #define TEST_H
4
+
5
+ #endif
@@ -0,0 +1,15 @@
1
+ # Autogenerated. Do not modify!
2
+ # Create additional tasks and make other modifications in custom.rf.
3
+
4
+ task :run => "test" do
5
+ sys "./test"
6
+ end
7
+
8
+ gen C::Dependencies
9
+ gen Action do source "c_dependencies" end
10
+
11
+ file "test" => sys["*.cpp"].sub_ext("o") do |t|
12
+ sys "g++ -o #{t.name} #{t.prerequisites}"
13
+ end
14
+
15
+ source "custom.rf" if File.exist? "custom.rf"
@@ -0,0 +1,6 @@
1
+
2
+ #include "another_test.h"
3
+
4
+ void another_test()
5
+ {
6
+ }
@@ -0,0 +1,7 @@
1
+
2
+ #ifndef ANOTHER_TEST_H
3
+ #define ANOTHER_TEST_H
4
+
5
+ void another_test(void);
6
+
7
+ #endif
@@ -0,0 +1,12 @@
1
+
2
+ #include <stdio.h>
3
+ #include "test.h"
4
+ #include "another_test.h"
5
+
6
+ int main(char argc, char** argv)
7
+ {
8
+ test();
9
+ another_test();
10
+ printf("Hello, world!\n");
11
+ return 0;
12
+ }
@@ -0,0 +1,6 @@
1
+
2
+ #include "test.h"
3
+
4
+ void test()
5
+ {
6
+ }
@@ -0,0 +1,7 @@
1
+
2
+ #ifndef TEST_H
3
+ #define TEST_H
4
+
5
+ void test(void);
6
+
7
+ #endif
@@ -0,0 +1,15 @@
1
+ # Autogenerated. Do not modify!
2
+ # Create additional tasks and make other modifications in custom.rf.
3
+
4
+ task :run => "test" do
5
+ sys "./test"
6
+ end
7
+
8
+ gen C::Dependencies
9
+ gen Action do source "c_dependencies" end
10
+
11
+ file "test" => sys["*.c"].sub_ext("o") do |t|
12
+ sys "gcc -o #{t.name} #{t.prerequisites}"
13
+ end
14
+
15
+ source "custom.rf" if File.exist? "custom.rf"
@@ -0,0 +1,46 @@
1
+
2
+ import "md5"
3
+ import "autoclean", "package/tgz", "c/dependencies"
4
+
5
+ cpp_dirs = sys["c++/problem_*"]
6
+ c_dirs = sys["c/problem_*"]
7
+ all_dirs = cpp_dirs + c_dirs
8
+
9
+ cpp_rf_template = "c++/template.rf"
10
+ c_rf_template = "c/template.rf"
11
+
12
+ desc "Run all C and C++ tests."
13
+ task :run => all_dirs.map{ |f| "#{f}/run" }
14
+ desc "Build all."
15
+ task :build => all_dirs.map{ |f| "#{f}/test" }
16
+
17
+ desc "Remove all autogenerated files."
18
+ gen AutoClean
19
+
20
+ gen Rule, '.o' => '.cpp' do |t|
21
+ sys "g++ -c -o #{t.name} #{t.source}"
22
+ end
23
+
24
+ gen Rule, '.o' => '.c' do |t|
25
+ sys "gcc -c -o #{t.name} #{t.source}"
26
+ end
27
+
28
+ desc "Create source package."
29
+ gen Package::Tgz, "pkg/c_cpp",
30
+ :files => sys["root.rant", "**/*.{c,cpp,h,rf}"]
31
+
32
+ gen Action do
33
+ cpp_dirs.each { |dir|
34
+ make "#{dir}/sub.rant" => cpp_rf_template do |t|
35
+ sys.cp t.source, t.name
36
+ end
37
+ }
38
+ c_dirs.each { |dir|
39
+ make "#{dir}/sub.rant" => c_rf_template do |t|
40
+ sys.cp t.source, t.name
41
+ end
42
+ }
43
+ subdirs cpp_dirs, c_dirs
44
+ end
45
+
46
+ # vim:ft=ruby
@@ -0,0 +1,115 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
5
+
6
+ <!--
7
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
8
+ "http://www.w3.org/TR/html4/strict.dtd">
9
+
10
+ <html>
11
+ -->
12
+ <head>
13
+ <title>Rant</title>
14
+ <style type="text/css" media="screen">@import "rant_home.css";</style>
15
+ </head>
16
+
17
+ <body>
18
+
19
+ <div class="content">
20
+ <h1>Rant - Flexible, Ruby based make</h1>
21
+ <p>
22
+ Similar to make, the rant commandline tool reads a file called
23
+ Rantfile, which contains task definitions. Unlike make, however, an
24
+ Rantfile is just a valid script written in the Ruby programming
25
+ language. Since Ruby comes with many useful libraries and is
26
+ portable across many different operating systems, it's very easy to
27
+ write portable Rantfiles.
28
+ </p>
29
+ <h2>Striking features:</h2>
30
+ <ul>
31
+ <li>Defining custom tasks.</li>
32
+ <li>Automated packaging, testing and RDoc generation for Ruby
33
+ applications and libraries.</li>
34
+ <li>Creation of a monolithic script tailored to the needs of a
35
+ specific project which can be used instead of an Rant
36
+ installation - users don't need to install Rant.</li>
37
+ <li>Creating gzipped tar and zip archives -- without installing
38
+ additional software.
39
+ </li>
40
+ <li>Optional recognition of file changes based on MD5
41
+ checksums instead of file modification times.
42
+ </li>
43
+ <li>Primitive support for compiling C# sources with csc, cscc
44
+ and mcs.</li>
45
+ <li>Dependency checking for C/C++ source files (integrated
46
+ makedepend replacement).</li>
47
+ </ul>
48
+ </div>
49
+
50
+ <div class="content">
51
+ <h2>Getting started</h2>
52
+ <dl>
53
+ <dt>1. Install Ruby</dt>
54
+ <dd>
55
+ Issue the command: <tt>% ruby --version</tt> <br/>
56
+ which prints the Ruby version number you've installed. If it
57
+ isn't equal or higher to 1.8.0, get a newer version from the <a
58
+ href="http://www.ruby-lang.org/en/">Ruby homepage</a> or
59
+ the <a href="http://rubyforge.org/projects/rubyinstaller/">One-Click Installer for Windows</a>.
60
+ </dd>
61
+ <dt>2. Install Rant</dt>
62
+ <dd>
63
+ Issue the command: <tt>% gem install --remote rant</tt><br/>
64
+ which should download and install Rant. If you don't have the
65
+ gem command, download the package from <a
66
+ href="http://rubyforge.org/frs/?group_id=615">RubyForge</a>,
67
+ unpack it and run <tt>% ruby install.rb</tt>.
68
+ </dd>
69
+ <dt>3. Read the <strong>documentation</strong></dt>
70
+ <dd>If you want to start with the basics, continue <a
71
+ href="files/doc/rantfile_rdoc.html">here</a>.
72
+ </dd>
73
+ <dd>If you want to get an overview, continue <a
74
+ href="files/README.html">here</a>.
75
+ </dd>
76
+ </dl>
77
+ </div>
78
+
79
+ <div id="navAlpha">
80
+ <h2>Links</h2>
81
+ <p>
82
+ <a href="files/NEWS.html">ChangeLog</a><br/>
83
+ <a href="api.html">API docs</a><br/>
84
+ <a href="http://rubyforge.org/projects/make/">Project page</a><br/>
85
+ <a title="Subscribe to mailing list"
86
+ href="http://rubyforge.org/mailman/listinfo/make-cafe">Mailing list</a><br/>
87
+ <a title="Browse mailing list archives"
88
+ href="http://rubyforge.org/pipermail/make-cafe/">List archives</a><br/>
89
+ <a
90
+ href="http://rubyforge.org/tracker/?func=add&amp;group_id=615&amp;atid=2428">Report a bug</a><br/>
91
+ </p>
92
+ </div>
93
+
94
+ <div id="navBeta">
95
+ <h2>Documentation</h2>
96
+ <a href="files/README.html">User Manual</a><br/>
97
+ <hr/>
98
+ <h2>Updating</h2>
99
+ <p>
100
+ Always read the <a href="files/NEWS.html">ChangeLog</a>
101
+ before installing a newer version of Rant. It describes
102
+ non-backwards compatible changes and new features.
103
+ </p>
104
+ </div>
105
+
106
+ <p>
107
+ <a href="http://validator.w3.org/check?uri=referer"><img
108
+ src="http://www.w3.org/Icons/valid-xhtml10"
109
+ alt="Valid XHTML 1.0!" height="31" width="88" /></a>
110
+ </p>
111
+
112
+ <!-- BlueRobot was here. -->
113
+
114
+ </body>
115
+ </html>