passenger 5.0.1 → 5.0.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/.editorconfig +10 -0
- data/CHANGELOG +12 -0
- data/CONTRIBUTING.md +10 -0
- data/CONTRIBUTORS +1 -0
- data/Gemfile +10 -10
- data/build/basics.rb +5 -1
- data/build/common_library.rb +33 -55
- data/build/debian.rb +2 -4
- data/build/packaging.rb +3 -3
- data/build/preprocessor.rb +3 -204
- data/debian.template/{control.template → control.erb} +18 -18
- data/debian.template/{locations.ini.template → locations.ini.erb} +0 -0
- data/debian.template/{passenger-dev.install.template → passenger-dev.install.erb} +0 -0
- data/debian.template/passenger-doc.install.erb +2 -0
- data/debian.template/{passenger.install.template → passenger.install.erb} +0 -0
- data/debian.template/{rules.template → rules.erb} +24 -23
- data/doc/users_guide_snippets/tips.txt +9 -1
- data/ext/common/Constants.h +3 -1
- data/ext/common/ServerKit/Channel.h +22 -4
- data/ext/common/ServerKit/Context.h +3 -1
- data/ext/common/ServerKit/FdSinkChannel.h +9 -1
- data/ext/common/ServerKit/FdSourceChannel.h +9 -1
- data/ext/common/ServerKit/FileBufferedChannel.h +19 -7
- data/ext/common/Utils/SystemMetricsCollector.h +0 -1
- data/ext/common/Utils/VariantMap.h +22 -1
- data/ext/common/agents/HelperAgent/Main.cpp +15 -0
- data/ext/common/agents/HelperAgent/OptionParser.h +6 -1
- data/ext/common/agents/HelperAgent/RequestHandler.h +3 -0
- data/lib/phusion_passenger.rb +1 -1
- data/lib/phusion_passenger/common_library.rb +13 -5
- data/lib/phusion_passenger/config/restart_app_command.rb +8 -4
- data/lib/phusion_passenger/constants.rb +1 -0
- data/lib/phusion_passenger/standalone/command.rb +1 -1
- data/lib/phusion_passenger/standalone/start_command.rb +8 -0
- data/lib/phusion_passenger/standalone/start_command/builtin_engine.rb +1 -0
- data/test/cxx/ServerKit/FileBufferedChannelTest.cpp +179 -4
- metadata +8 -8
- metadata.gz.asc +7 -7
- data/debian.template/passenger-doc.install.template +0 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
N2JiN2YxMTU2OTZmZTQzMzIwMTk1MWM4ZGZkYzZlZmJmMjdiZTM3NA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YWQ0YzJmMDg0MzMwYzBkOGQwZjExYWIzMjA1ZGM4MTAxMDE5NDNkZQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZGZhMjdiMTZhYTk1MDRiMTYxNTlhMjhiZjNmZDI3OTBmYWZkZmEzM2ZkMDY5
|
10
|
+
ZTU4MDRmZWU1NjdiOTYxZjk2OGM0YmE3ZmZkNzU2YjRmZGIwMzI1M2UxYmU2
|
11
|
+
YTBmYWEyNzdlZWYzMzQ0YzczYmRiNjcwYTVjMDQzMTVjNjBiMmM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MzliMDhiMjI5MzM2NTZjNmUwYmQ4MWVhNmZiY2EwYTczNGY0NzI1YzAwMzQ4
|
14
|
+
MmQwZTQwZTI0Y2U2NjBiY2ZmZGQzZTI1YmVjN2MzMjNkNTUwOTk0NDJiZTI3
|
15
|
+
ZThhZTk0MzFjODY2NjQ1NWFlMzBiOTkwZWM0NTNmYmI4MjljYzY=
|
checksums.yaml.gz.asc
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
|
3
3
|
Comment: GPGTools - http://gpgtools.org
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
=
|
5
|
+
iQEcBAABAgAGBQJU+skQAAoJECrHRaUKISqMCYEIALFilhp8+SVXIUbPuDbRWt+0
|
6
|
+
V8JijFYyXw1Jiy5VFW5V20Zu70okzRXd9V+u3UvgdRkftqrIPsp4b+vW18pAeg4i
|
7
|
+
Gse7Wjr53xMvNthIZKqC0BY6zi9FurzkgP4r0hkd2cLmcjB53NNui7nPuYt9mMwH
|
8
|
+
+WplJeAazcISRhQRJnlBLMDrVWesgJMj+xP/8SaKGsIYfVju8m78TI+hl0X+XT0T
|
9
|
+
qt9zZDLRd7EpJUS5BovYAFiU7ljLXeFt9bmvN23kZ1MB49GpaPe9hA9L8pRhZmOT
|
10
|
+
7oyLImaMKFprjwL+vPS8JYM0b+NVYkT1ALki08yEoKIpwtnujkNFr6KpHAyGSFc=
|
11
|
+
=o0Sc
|
12
12
|
-----END PGP SIGNATURE-----
|
data.tar.gz.asc
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
Version: GnuPG/MacGPG2 v2.0.17 (Darwin)
|
3
3
|
Comment: GPGTools - http://gpgtools.org
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
=
|
5
|
+
iQEcBAABAgAGBQJU+skQAAoJECrHRaUKISqM3w8IALm2kOp7hWd1Qy4mvAl7czSb
|
6
|
+
b+V/QGy14Mlt+v24GIuVjl88CaX4qA3eHGzsBNb807+L3pc/PYPi7qd0pf0hEN6x
|
7
|
+
kL730RkjnSFvpuLE37kuemtStVUKHnO8jxMbGWMUZEdEOLThw4LkeDKJPAjm2M2V
|
8
|
+
dWuHzzdFsA3tb79dy6dL8SSkpqwpfHhpeCdHbgZXhMq+PhllCieeICuwBvZeSOvE
|
9
|
+
mOwAqt5Toq1KNoKPE/gOPiywGsNQgLYn6HXYTuHrCz/p8YMjJOiTEMODTJD4io4V
|
10
|
+
cF6byuXfikIouVBgkZQYbwuItMlpJr9e4oZidjBZ7trFmqOT1FnnFiMUehsaHzw=
|
11
|
+
=h4HJ
|
12
12
|
-----END PGP SIGNATURE-----
|
data/.editorconfig
CHANGED
@@ -53,6 +53,16 @@ indent_style = space
|
|
53
53
|
indent_size = 2
|
54
54
|
trim_trailing_whitespace = true
|
55
55
|
|
56
|
+
[Rakefile]
|
57
|
+
indent_style = space
|
58
|
+
indent_size = 2
|
59
|
+
trim_trailing_whitespace = true
|
60
|
+
|
61
|
+
[Gemfile]
|
62
|
+
indent_style = space
|
63
|
+
indent_size = 2
|
64
|
+
trim_trailing_whitespace = true
|
65
|
+
|
56
66
|
[*.js]
|
57
67
|
indent_style = tab
|
58
68
|
indent_size = 4
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
Release 5.0.2
|
2
|
+
-------------
|
3
|
+
|
4
|
+
* Fixes a connection freeze that could occur when processing large responses. This would manifest itself under the error message "This website is under heavy load" or "Request queue is full, returning an error". Closes GH-1404.
|
5
|
+
* Debian and Ubuntu packages have been reintroduces.
|
6
|
+
* When `passenger-config restart-app` is run interactively, if Passenger is not serving any applications, then the command now prints an error message instead of showing a menu with only a "Cancel" option.
|
7
|
+
* Fixes a compilation problem on FreeBSD 10 (contributed by: clemensg). Closes GH-1401.
|
8
|
+
* [Standalone] Fixes a crash that would occur if you use the `--ctl` parameter.
|
9
|
+
* [Enterprise] The `--max-request-time` option has been added to Passenger Standalone.
|
10
|
+
* [Enterprise] The `max_request_time_reached` hook has been introduced. This hook allows you to run diagnostics on a process that that took too long to respond to a request.
|
11
|
+
|
12
|
+
|
1
13
|
Release 5.0.1
|
2
14
|
-------------
|
3
15
|
|
data/CONTRIBUTING.md
CHANGED
@@ -17,6 +17,7 @@
|
|
17
17
|
* [Ruby coding style](#ruby_coding_style)
|
18
18
|
* [Systems programming fundamentals](#systems_programming_fundamentals)
|
19
19
|
* [Further reading](#further_reading)
|
20
|
+
* [Git structure] (#git_structure)
|
20
21
|
|
21
22
|
Thank you for your interest in Phusion Passenger. Phusion Passenger is open source so your contributions are very welcome. Although we also provide a [commercial version](https://www.phusionpassenger.com/enterprise) and [commercial support](https://www.phusionpassenger.com/commercial_support), the core remains open source and we remain committed to keep it that way. This guide gives you an overview of the ways with which you can contribute, as well as contribution guidelines.
|
22
23
|
|
@@ -348,3 +349,12 @@ A good and comprehensive, but rather large source for learning POSIX is the [POS
|
|
348
349
|
### Further reading
|
349
350
|
|
350
351
|
* [Coding Tips and Pitfalls](https://github.com/phusion/passenger/blob/master/doc/CodingTipsAndPitfalls.md)
|
352
|
+
|
353
|
+
<a name="git_structure"></a>
|
354
|
+
### Git structure
|
355
|
+
|
356
|
+
The **master** branch is the main development branch, containing the latest and greatest code that was tested and accepted for inclusion into passenger (usually merged in from loose development branches that are deleted afterwards). This branch may not be stable enough yet for production.
|
357
|
+
|
358
|
+
Branches like **stable-4.0**, **stable-5.0** are production quality branches (split off from master) for major versions. Each production branch has tags for minor versions, whereby **tag x.0.1** represents the first production-ready version on a branch (there may be some release candidates before that). For example: branch stable-5.0, tagged 5.0.1 is the first release of the 5.0 line that is ready for production.
|
359
|
+
|
360
|
+
In general we apply fixes to the respective stable branch and merge these into the master, so it is easiest if you submit pull requests to the stable branches (unless of course you are working with the unstable master). Conversely, new features always go to the master and are then cherrypicked from one or more branches.
|
data/CONTRIBUTORS
CHANGED
data/Gemfile
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
source 'https://rubygems.org/'
|
2
2
|
|
3
3
|
group :base do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
gem 'mime-types', '1.25'
|
5
|
+
gem 'rspec', '2.14.1'
|
6
|
+
gem 'rake'
|
7
|
+
gem 'drake'
|
8
|
+
gem 'json'
|
9
|
+
gem 'rack'
|
10
10
|
end
|
11
11
|
|
12
12
|
group :doc do
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
# Last version that worked on Ruby 1.8
|
14
|
+
gem 'nokogiri', '1.5.9'
|
15
|
+
gem 'mizuho'
|
16
|
+
gem 'bluecloth'
|
17
17
|
end
|
data/build/basics.rb
CHANGED
@@ -146,15 +146,19 @@ USE_DMALLOC = boolean_option('USE_DMALLOC')
|
|
146
146
|
USE_EFENCE = boolean_option('USE_EFENCE')
|
147
147
|
USE_ASAN = boolean_option('USE_ASAN')
|
148
148
|
OPTIMIZE = boolean_option('OPTIMIZE')
|
149
|
+
LTO = OPTIMIZE && boolean_option('LTO')
|
149
150
|
|
150
151
|
# Agent-specific compiler flags.
|
151
152
|
AGENT_CFLAGS = ""
|
152
|
-
AGENT_CFLAGS << " #{PlatformInfo.adress_sanitizer_flag}" if USE_ASAN
|
153
153
|
AGENT_CFLAGS << " -O" if OPTIMIZE
|
154
|
+
AGENT_CFLAGS << " -flto" if LTO
|
155
|
+
AGENT_CFLAGS << " #{PlatformInfo.adress_sanitizer_flag}" if USE_ASAN
|
154
156
|
AGENT_CFLAGS.strip!
|
155
157
|
|
156
158
|
# Agent-specific linker flags.
|
157
159
|
AGENT_LDFLAGS = ""
|
160
|
+
AGENT_LDFLAGS << " -O" if OPTIMIZE
|
161
|
+
AGENT_LDFLAGS << " -flto" if LTO
|
158
162
|
AGENT_LDFLAGS << " #{PlatformInfo.dmalloc_ldflags}" if USE_DMALLOC
|
159
163
|
AGENT_LDFLAGS << " #{PlatformInfo.electric_fence_ldflags}" if USE_EFENCE
|
160
164
|
AGENT_LDFLAGS << " #{PlatformInfo.adress_sanitizer_flag}" if USE_ASAN
|
data/build/common_library.rb
CHANGED
@@ -36,66 +36,44 @@ def define_libboost_oxt_task(namespace, output_dir, extra_compiler_flags = nil)
|
|
36
36
|
output_file = "#{output_dir}.a"
|
37
37
|
flags = "-Iext #{extra_compiler_flags} #{EXTRA_CXXFLAGS}"
|
38
38
|
|
39
|
-
if
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
sources = Dir['ext/boost/libs/**/*.cpp'] + Dir['ext/oxt/*.cpp']
|
44
|
-
sources.sort!
|
45
|
-
|
46
|
-
aggregate_source = "#{output_dir}/aggregate.cpp"
|
47
|
-
aggregate_object = "#{output_dir}/aggregate.o"
|
48
|
-
object_files = [aggregate_object]
|
49
|
-
|
50
|
-
file(aggregate_object => sources) do
|
51
|
-
sh "mkdir -p #{output_dir}" if !File.directory?(output_dir)
|
52
|
-
aggregate_content = %Q{
|
53
|
-
#ifndef _GNU_SOURCE
|
54
|
-
#define _GNU_SOURCE
|
55
|
-
#endif
|
56
|
-
}
|
57
|
-
sources.each do |source_file|
|
58
|
-
name = source_file.sub(/^ext\//, '')
|
59
|
-
aggregate_content << "#include \"#{name}\"\n"
|
60
|
-
end
|
61
|
-
File.open(aggregate_source, 'w') do |f|
|
62
|
-
f.write(aggregate_content)
|
63
|
-
end
|
64
|
-
compile_cxx(aggregate_source, "#{flags} -o #{aggregate_object}")
|
65
|
-
end
|
66
|
-
else
|
67
|
-
# Define compilation targets for .cpp files in ext/boost/src/pthread.
|
68
|
-
boost_object_files = []
|
69
|
-
Dir['ext/boost/libs/**/*.cpp'].each do |source_file|
|
70
|
-
object_name = File.basename(source_file.sub(/\.cpp$/, '.o'))
|
71
|
-
boost_output_dir = "#{output_dir}/boost"
|
72
|
-
object_file = "#{boost_output_dir}/#{object_name}"
|
73
|
-
boost_object_files << object_file
|
74
|
-
|
75
|
-
file object_file => source_file do
|
76
|
-
sh "mkdir -p #{boost_output_dir}" if !File.directory?(boost_output_dir)
|
77
|
-
compile_cxx(source_file, "#{flags} -o #{object_file}")
|
78
|
-
end
|
39
|
+
if OPTIMIZE
|
40
|
+
optimize = "-O2"
|
41
|
+
if LTO
|
42
|
+
optimize << " -flto"
|
79
43
|
end
|
44
|
+
end
|
80
45
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
compile_cxx(source_file, "-O2 #{flags} -o #{object_file}".strip)
|
93
|
-
end
|
46
|
+
# Define compilation targets for .cpp files in ext/boost/src/pthread.
|
47
|
+
boost_object_files = []
|
48
|
+
Dir['ext/boost/libs/**/*.cpp'].each do |source_file|
|
49
|
+
object_name = File.basename(source_file.sub(/\.cpp$/, '.o'))
|
50
|
+
boost_output_dir = "#{output_dir}/boost"
|
51
|
+
object_file = "#{boost_output_dir}/#{object_name}"
|
52
|
+
boost_object_files << object_file
|
53
|
+
|
54
|
+
file object_file => source_file do
|
55
|
+
sh "mkdir -p #{boost_output_dir}" if !File.directory?(boost_output_dir)
|
56
|
+
compile_cxx(source_file, "#{optimize} #{flags} -o #{object_file}")
|
94
57
|
end
|
58
|
+
end
|
95
59
|
|
96
|
-
|
60
|
+
# Define compilation targets for .cpp files in ext/oxt.
|
61
|
+
oxt_object_files = []
|
62
|
+
oxt_dependency_files = Dir["ext/oxt/*.hpp"] + Dir["ext/oxt/detail/*.hpp"]
|
63
|
+
Dir['ext/oxt/*.cpp'].each do |source_file|
|
64
|
+
object_name = File.basename(source_file.sub(/\.cpp$/, '.o'))
|
65
|
+
oxt_output_dir = "#{output_dir}/oxt"
|
66
|
+
object_file = "#{oxt_output_dir}/#{object_name}"
|
67
|
+
oxt_object_files << object_file
|
68
|
+
|
69
|
+
file object_file => [source_file, *oxt_dependency_files] do
|
70
|
+
sh "mkdir -p #{oxt_output_dir}" if !File.directory?(oxt_output_dir)
|
71
|
+
compile_cxx(source_file, "#{optimize} #{flags} -o #{object_file}".strip)
|
72
|
+
end
|
97
73
|
end
|
98
74
|
|
75
|
+
object_files = boost_object_files + oxt_object_files
|
76
|
+
|
99
77
|
file(output_file => object_files) do
|
100
78
|
sh "mkdir -p #{output_dir}"
|
101
79
|
create_static_library(output_file, object_files.join(' '))
|
@@ -238,5 +216,5 @@ libboost_oxt_cflags = ""
|
|
238
216
|
libboost_oxt_cflags << " #{PlatformInfo.adress_sanitizer_flag}" if USE_ASAN
|
239
217
|
libboost_oxt_cflags.strip!
|
240
218
|
LIBBOOST_OXT = define_libboost_oxt_task("common", COMMON_OUTPUT_DIR + "libboost_oxt", libboost_oxt_cflags)
|
241
|
-
COMMON_LIBRARY.enable_optimizations! if OPTIMIZE
|
219
|
+
COMMON_LIBRARY.enable_optimizations!(LTO) if OPTIMIZE
|
242
220
|
COMMON_LIBRARY.define_tasks(libboost_oxt_cflags)
|
data/build/debian.rb
CHANGED
@@ -102,8 +102,7 @@ task 'debian:dev' do
|
|
102
102
|
sh "cd #{PKG_DIR}/#{distribution} && dpkg-checkbuilddeps"
|
103
103
|
end
|
104
104
|
distributions.each do |distribution|
|
105
|
-
sh "cd #{PKG_DIR}/#{distribution} &&
|
106
|
-
"debuild -e CCACHE_* -us -uc"
|
105
|
+
sh "cd #{PKG_DIR}/#{distribution} && debuild -e CCACHE_* -us -uc -F"
|
107
106
|
end
|
108
107
|
end
|
109
108
|
|
@@ -147,8 +146,7 @@ task 'debian:source_packages' => 'debian:orig_tarball' do
|
|
147
146
|
create_debian_package_dir(distribution, pkg_dir)
|
148
147
|
end
|
149
148
|
ALL_DISTRIBUTIONS.each do |distribution|
|
150
|
-
sh "cd #{pkg_dir}/#{distribution} &&
|
151
|
-
"debuild -us -uc"
|
149
|
+
sh "cd #{pkg_dir}/#{distribution} && debuild -us -uc -S"
|
152
150
|
end
|
153
151
|
end
|
154
152
|
|
data/build/packaging.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# Phusion Passenger - https://www.phusionpassenger.com/
|
2
|
-
# Copyright (c) 2010-
|
2
|
+
# Copyright (c) 2010-2015 Phusion
|
3
3
|
#
|
4
4
|
# "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
|
5
5
|
#
|
@@ -34,8 +34,8 @@ def recursive_copy_files(files, destination_dir, preprocess = false, variables =
|
|
34
34
|
FileUtils.mkdir_p("#{destination_dir}/#{dir}")
|
35
35
|
end
|
36
36
|
if !File.directory?(filename)
|
37
|
-
if preprocess && filename =~ /\.
|
38
|
-
real_filename = filename.sub(/\.
|
37
|
+
if preprocess && filename =~ /\.erb$/
|
38
|
+
real_filename = filename.sub(/\.erb$/, '')
|
39
39
|
FileUtils.install(filename, "#{destination_dir}/#{real_filename}", :preserve => true)
|
40
40
|
Preprocessor.new.start(filename, "#{destination_dir}/#{real_filename}",
|
41
41
|
variables)
|
data/build/preprocessor.rb
CHANGED
@@ -22,43 +22,9 @@
|
|
22
22
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
23
|
# THE SOFTWARE.
|
24
24
|
|
25
|
-
# Implements a simple preprocessor language which combines elements in the C
|
26
|
-
# preprocessor with ERB:
|
27
|
-
#
|
28
|
-
# Today
|
29
|
-
# #if @today == :fine
|
30
|
-
# is a fine day.
|
31
|
-
# #elif @today == :good
|
32
|
-
# is a good day.
|
33
|
-
# #else
|
34
|
-
# is a sad day.
|
35
|
-
# #endif
|
36
|
-
# Let's go walking.
|
37
|
-
# Today is <%= Time.now %>.
|
38
|
-
#
|
39
|
-
# When run with...
|
40
|
-
#
|
41
|
-
# Preprocessor.new.start('input.txt', 'output.txt', :today => :fine)
|
42
|
-
#
|
43
|
-
# ...will produce:
|
44
|
-
#
|
45
|
-
# Today
|
46
|
-
# is a fine day.
|
47
|
-
# Let's go walking.
|
48
|
-
# Today is 2013-08-11 22:37:06 +0200.
|
49
|
-
#
|
50
|
-
# Highlights:
|
51
|
-
#
|
52
|
-
# * #if blocks can be nested.
|
53
|
-
# * Expressions are Ruby expressions, evaluated within the binding of a
|
54
|
-
# Preprocessor::Evaluator object.
|
55
|
-
# * Text inside #if/#elif/#else are automatically unindented.
|
56
|
-
# * ERB compatible.
|
57
25
|
class Preprocessor
|
58
26
|
def initialize
|
59
27
|
require 'erb' if !defined?(ERB)
|
60
|
-
@indentation_size = 4
|
61
|
-
@debug = boolean_option('DEBUG')
|
62
28
|
end
|
63
29
|
|
64
30
|
def start(filename, output_filename, variables = {})
|
@@ -69,99 +35,10 @@ class Preprocessor
|
|
69
35
|
output = STDOUT
|
70
36
|
end
|
71
37
|
the_binding = create_binding(variables)
|
72
|
-
context = []
|
73
|
-
@filename = filename
|
74
|
-
@lineno = 1
|
75
|
-
@indentation = 0
|
76
|
-
|
77
|
-
each_line(filename, the_binding) do |line|
|
78
|
-
debug("context=#{context.inspect}, line=#{line.inspect}")
|
79
|
-
|
80
|
-
name, args_string, cmd_indentation = recognize_command(line)
|
81
|
-
case name
|
82
|
-
when "if"
|
83
|
-
case context.last
|
84
|
-
when nil, :if_true, :else_true
|
85
|
-
check_indentation(cmd_indentation)
|
86
|
-
result = the_binding.eval(args_string, filename, @lineno)
|
87
|
-
context.push(result ? :if_true : :if_false)
|
88
|
-
inc_indentation
|
89
|
-
when :if_false, :else_false, :if_ignore
|
90
|
-
check_indentation(cmd_indentation)
|
91
|
-
inc_indentation
|
92
|
-
context.push(:if_ignore)
|
93
|
-
else
|
94
|
-
terminate "#if is not allowed in this context"
|
95
|
-
end
|
96
|
-
when "elif"
|
97
|
-
case context.last
|
98
|
-
when :if_true
|
99
|
-
dec_indentation
|
100
|
-
check_indentation(cmd_indentation)
|
101
|
-
inc_indentation
|
102
|
-
context[-1] = :if_false
|
103
|
-
when :if_false
|
104
|
-
dec_indentation
|
105
|
-
check_indentation(cmd_indentation)
|
106
|
-
inc_indentation
|
107
|
-
result = the_binding.eval(args_string, filename, @lineno)
|
108
|
-
context[-1] = result ? :if_true : :if_false
|
109
|
-
when :else_true, :else_false
|
110
|
-
terminate "#elif is not allowed after #else"
|
111
|
-
when :if_ignore
|
112
|
-
dec_indentation
|
113
|
-
check_indentation(cmd_indentation)
|
114
|
-
inc_indentation
|
115
|
-
else
|
116
|
-
terminate "#elif is not allowed outside #if block"
|
117
|
-
end
|
118
|
-
when "else"
|
119
|
-
case context.last
|
120
|
-
when :if_true
|
121
|
-
dec_indentation
|
122
|
-
check_indentation(cmd_indentation)
|
123
|
-
inc_indentation
|
124
|
-
context[-1] = :else_false
|
125
|
-
when :if_false
|
126
|
-
dec_indentation
|
127
|
-
check_indentation(cmd_indentation)
|
128
|
-
inc_indentation
|
129
|
-
context[-1] = :else_true
|
130
|
-
when :else_true, :else_false
|
131
|
-
terminate "it is not allowed to have multiple #else clauses in one #if block"
|
132
|
-
when :if_ignore
|
133
|
-
dec_indentation
|
134
|
-
check_indentation(cmd_indentation)
|
135
|
-
inc_indentation
|
136
|
-
else
|
137
|
-
terminate "#else is not allowed outside #if block"
|
138
|
-
end
|
139
|
-
when "endif"
|
140
|
-
case context.last
|
141
|
-
when :if_true, :if_false, :else_true, :else_false, :if_ignore
|
142
|
-
dec_indentation
|
143
|
-
check_indentation(cmd_indentation)
|
144
|
-
context.pop
|
145
|
-
else
|
146
|
-
terminate "#endif is not allowed outside #if block"
|
147
|
-
end
|
148
|
-
when "DEBHELPER"
|
149
|
-
output.puts(line)
|
150
|
-
when "", nil
|
151
|
-
# Either a comment or not a preprocessor command.
|
152
|
-
case context.last
|
153
|
-
when nil, :if_true, :else_true
|
154
|
-
output.puts(unindent(line))
|
155
|
-
else
|
156
|
-
# Check indentation but do not output.
|
157
|
-
unindent(line)
|
158
|
-
end
|
159
|
-
else
|
160
|
-
terminate "Unrecognized preprocessor command ##{name.inspect}"
|
161
|
-
end
|
162
38
|
|
163
|
-
|
164
|
-
|
39
|
+
erb = ERB.new(File.read(filename), nil, "-")
|
40
|
+
erb.filename = filename
|
41
|
+
output.write(erb.result(the_binding))
|
165
42
|
ensure
|
166
43
|
if output_filename && output
|
167
44
|
output.close
|
@@ -251,37 +128,6 @@ private
|
|
251
128
|
end
|
252
129
|
end
|
253
130
|
|
254
|
-
def each_line(filename, the_binding)
|
255
|
-
data = File.open(filename, 'r') do |f|
|
256
|
-
erb = ERB.new(f.read, nil, "-")
|
257
|
-
erb.filename = filename
|
258
|
-
erb.result(the_binding)
|
259
|
-
end
|
260
|
-
data.each_line do |line|
|
261
|
-
yield line.chomp
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
def recognize_command(line)
|
266
|
-
if line =~ /^([\s\t]*)#(.+)/
|
267
|
-
indentation_str = $1
|
268
|
-
command = $2
|
269
|
-
|
270
|
-
# Declare tabs as equivalent to 4 spaces. This is necessary for
|
271
|
-
# Makefiles in which the use of tabs is required.
|
272
|
-
indentation_str.gsub!("\t", " ")
|
273
|
-
|
274
|
-
name = command.scan(/^\w+/).first
|
275
|
-
# Ignore shebangs and comments.
|
276
|
-
return if name.nil?
|
277
|
-
|
278
|
-
args_string = command.sub(/^#{Regexp.escape(name)}[\s\t]*/, '')
|
279
|
-
return [name, args_string, indentation_str.to_s.size]
|
280
|
-
else
|
281
|
-
return nil
|
282
|
-
end
|
283
|
-
end
|
284
|
-
|
285
131
|
def create_binding(variables)
|
286
132
|
object = Evaluator.new
|
287
133
|
variables.each_pair do |key, val|
|
@@ -291,51 +137,4 @@ private
|
|
291
137
|
binding
|
292
138
|
end
|
293
139
|
end
|
294
|
-
|
295
|
-
def inc_indentation
|
296
|
-
@indentation += @indentation_size
|
297
|
-
end
|
298
|
-
|
299
|
-
def dec_indentation
|
300
|
-
@indentation -= @indentation_size
|
301
|
-
end
|
302
|
-
|
303
|
-
def check_indentation(expected)
|
304
|
-
if expected != @indentation
|
305
|
-
terminate "wrong indentation: found #{expected} characters, should be #{@indentation}"
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
def unindent(line)
|
310
|
-
line =~ /^([\s\t]*)/
|
311
|
-
# Declare tabs as equivalent to 4 spaces. This is necessary for
|
312
|
-
# Makefiles in which the use of tabs is required.
|
313
|
-
found = $1.to_s.gsub("\t", " ").size
|
314
|
-
|
315
|
-
if found >= @indentation
|
316
|
-
# Tab-friendly way to remove indentation.
|
317
|
-
remaining = @indentation
|
318
|
-
line = line.dup
|
319
|
-
while remaining > 0
|
320
|
-
if line[0..0] == " "
|
321
|
-
remaining -= 1
|
322
|
-
else
|
323
|
-
# This is a tab.
|
324
|
-
remaining -= 4
|
325
|
-
end
|
326
|
-
line.slice!(0, 1)
|
327
|
-
end
|
328
|
-
return line
|
329
|
-
else
|
330
|
-
terminate "wrong indentation: found #{found} characters, should be at least #{@indentation}"
|
331
|
-
end
|
332
|
-
end
|
333
|
-
|
334
|
-
def debug(message)
|
335
|
-
puts "DEBUG:#{@lineno}: #{message}" if @debug
|
336
|
-
end
|
337
|
-
|
338
|
-
def terminate(message)
|
339
|
-
abort "*** ERROR: #{@filename} line #{@lineno}: #{message}"
|
340
|
-
end
|
341
140
|
end
|