gettext 1.1.1-mswin32 → 1.2.0-mswin32

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 (157) hide show
  1. data/ChangeLog +128 -0
  2. data/NEWS +10 -0
  3. data/README +21 -23
  4. data/Rakefile +40 -21
  5. data/bin/rgettext +1 -1
  6. data/bin/rmsgfmt +1 -1
  7. data/bin/rmsgmerge +1 -1
  8. data/data/locale/cs/LC_MESSAGES/rails.mo +0 -0
  9. data/data/locale/cs/LC_MESSAGES/rgettext.mo +0 -0
  10. data/data/locale/de/LC_MESSAGES/rails.mo +0 -0
  11. data/data/locale/de/LC_MESSAGES/rgettext.mo +0 -0
  12. data/data/locale/el/LC_MESSAGES/rails.mo +0 -0
  13. data/data/locale/el/LC_MESSAGES/rgettext.mo +0 -0
  14. data/data/locale/es/LC_MESSAGES/rails.mo +0 -0
  15. data/data/locale/es/LC_MESSAGES/rgettext.mo +0 -0
  16. data/data/locale/fr/LC_MESSAGES/rails.mo +0 -0
  17. data/data/locale/fr/LC_MESSAGES/rgettext.mo +0 -0
  18. data/data/locale/it/LC_MESSAGES/rgettext.mo +0 -0
  19. data/data/locale/ja/LC_MESSAGES/rails.mo +0 -0
  20. data/data/locale/ja/LC_MESSAGES/rgettext.mo +0 -0
  21. data/data/locale/ko/LC_MESSAGES/rails.mo +0 -0
  22. data/data/locale/ko/LC_MESSAGES/rgettext.mo +0 -0
  23. data/data/locale/nl/LC_MESSAGES/rails.mo +0 -0
  24. data/data/locale/nl/LC_MESSAGES/rgettext.mo +0 -0
  25. data/data/locale/pt_BR/LC_MESSAGES/rails.mo +0 -0
  26. data/data/locale/pt_BR/LC_MESSAGES/rgettext.mo +0 -0
  27. data/data/locale/sv/LC_MESSAGES/rgettext.mo +0 -0
  28. data/ext/gettext/{gettext/Makefile → Makefile} +3 -3
  29. data/ext/gettext/extconf.rb +20 -0
  30. data/ext/gettext/locale_system-i386-mswin32.def +2 -0
  31. data/ext/gettext/{gettext/_locale.c → locale_system.c} +15 -19
  32. data/ext/gettext/locale_system.exp +0 -0
  33. data/ext/gettext/locale_system.lib +0 -0
  34. data/ext/gettext/locale_system.obj +0 -0
  35. data/ext/gettext/{gettext/_locale.pdb → locale_system.pdb} +0 -0
  36. data/ext/gettext/locale_system.so +0 -0
  37. data/ext/gettext/mkmf.log +10 -0
  38. data/ext/gettext/{gettext/vc70.pdb → vc70.pdb} +0 -0
  39. data/lib/gettext.rb +186 -38
  40. data/lib/gettext/cgi.rb +35 -69
  41. data/lib/gettext/container.rb +14 -5
  42. data/lib/gettext/erb.rb +30 -2
  43. data/lib/gettext/iconv.rb +19 -4
  44. data/lib/gettext/locale.rb +188 -39
  45. data/lib/gettext/locale_cgi.rb +102 -0
  46. data/lib/gettext/locale_object.rb +131 -0
  47. data/lib/gettext/locale_posix.rb +50 -0
  48. data/lib/gettext/locale_table_win32.rb +224 -182
  49. data/lib/gettext/locale_win32.rb +59 -35
  50. data/lib/gettext/mo.rb +2 -2
  51. data/lib/gettext/parser/activerecord.rb +19 -5
  52. data/lib/gettext/parser/erb.rb +6 -3
  53. data/lib/gettext/parser/glade.rb +5 -5
  54. data/lib/gettext/parser/ruby.rb +6 -6
  55. data/lib/gettext/poparser.rb +298 -297
  56. data/lib/gettext/rails.rb +122 -44
  57. data/lib/gettext/rgettext.rb +21 -8
  58. data/lib/gettext/rmsgfmt.rb +16 -8
  59. data/lib/gettext/rmsgmerge.rb +172 -50
  60. data/lib/gettext/string.rb +25 -3
  61. data/lib/gettext/textdomain.rb +89 -90
  62. data/lib/gettext/utils.rb +63 -3
  63. data/lib/gettext/version.rb +2 -2
  64. data/lib/locale_system.so +0 -0
  65. data/po/cs/rails.po +28 -28
  66. data/po/cs/rgettext.po +14 -14
  67. data/po/de/rails.po +29 -26
  68. data/po/de/rgettext.po +24 -17
  69. data/po/el/rails.po +26 -26
  70. data/po/el/rgettext.po +18 -15
  71. data/po/es/rails.po +26 -26
  72. data/po/es/rgettext.po +16 -16
  73. data/po/fr/rails.po +27 -27
  74. data/po/fr/rgettext.po +14 -14
  75. data/po/it/rgettext.po +14 -14
  76. data/po/ja/rails.po +24 -24
  77. data/po/ja/rgettext.po +14 -14
  78. data/po/ko/rails.po +24 -24
  79. data/po/ko/rgettext.po +17 -18
  80. data/po/nl/rails.po +27 -27
  81. data/po/nl/rgettext.po +18 -18
  82. data/po/pt_BR/rails.po +26 -26
  83. data/po/pt_BR/rgettext.po +14 -14
  84. data/po/rails.pot +26 -26
  85. data/po/rgettext.pot +14 -14
  86. data/po/sv/rgettext.po +14 -14
  87. data/post-setup.rb +8 -3
  88. data/pre-setup.rb +14 -1
  89. data/samples/cgi/http.rb +2 -1
  90. data/samples/makemo.rb +1 -1
  91. data/samples/rails/app/models/article.rb +15 -1
  92. data/samples/rails/config/database.yml +1 -1
  93. data/samples/rails/locale/cs/LC_MESSAGES/blog.mo +0 -0
  94. data/samples/rails/locale/cs/LC_MESSAGES/gettext_plugin.mo +0 -0
  95. data/samples/rails/locale/de/LC_MESSAGES/blog.mo +0 -0
  96. data/samples/rails/locale/de/LC_MESSAGES/gettext_plugin.mo +0 -0
  97. data/samples/rails/locale/el/LC_MESSAGES/blog.mo +0 -0
  98. data/samples/rails/locale/el/LC_MESSAGES/gettext_plugin.mo +0 -0
  99. data/samples/rails/locale/en/LC_MESSAGES/blog.mo +0 -0
  100. data/samples/rails/locale/es/LC_MESSAGES/blog.mo +0 -0
  101. data/samples/rails/locale/es/LC_MESSAGES/gettext_plugin.mo +0 -0
  102. data/samples/rails/locale/fr/LC_MESSAGES/blog.mo +0 -0
  103. data/samples/rails/locale/fr/LC_MESSAGES/gettext_plugin.mo +0 -0
  104. data/samples/rails/locale/ja/LC_MESSAGES/blog.mo +0 -0
  105. data/samples/rails/locale/ja/LC_MESSAGES/gettext_plugin.mo +0 -0
  106. data/samples/rails/locale/ko/LC_MESSAGES/blog.mo +0 -0
  107. data/samples/rails/locale/ko/LC_MESSAGES/gettext_plugin.mo +0 -0
  108. data/samples/rails/locale/nl/LC_MESSAGES/blog.mo +0 -0
  109. data/samples/rails/locale/nl/LC_MESSAGES/gettext_plugin.mo +0 -0
  110. data/samples/rails/locale/pt_BR/LC_MESSAGES/blog.mo +0 -0
  111. data/samples/rails/locale/pt_BR/LC_MESSAGES/gettext_plugin.mo +0 -0
  112. data/samples/rails/po/blog.pot +1 -1
  113. data/samples/rails/po/cs/blog.po +1 -2
  114. data/samples/rails/po/cs/gettext_plugin.po +1 -1
  115. data/samples/rails/po/de/blog.po +1 -2
  116. data/samples/rails/po/de/gettext_plugin.po +1 -1
  117. data/samples/rails/po/el/blog.po +1 -1
  118. data/samples/rails/po/el/gettext_plugin.po +1 -1
  119. data/samples/rails/po/en/blog.po +1 -1
  120. data/samples/rails/po/es/blog.po +1 -2
  121. data/samples/rails/po/es/gettext_plugin.po +1 -1
  122. data/samples/rails/po/fr/blog.po +1 -1
  123. data/samples/rails/po/fr/gettext_plugin.po +1 -1
  124. data/samples/rails/po/gettext_plugin.pot +1 -1
  125. data/samples/rails/po/ja/blog.po +2 -1
  126. data/samples/rails/po/ja/gettext_plugin.po +1 -1
  127. data/samples/rails/po/ko/blog.po +1 -2
  128. data/samples/rails/po/ko/gettext_plugin.po +1 -1
  129. data/samples/rails/po/nl/blog.po +1 -3
  130. data/samples/rails/po/nl/gettext_plugin.po +1 -1
  131. data/samples/rails/po/pt_BR/blog.po +1 -1
  132. data/samples/rails/po/pt_BR/gettext_plugin.po +1 -1
  133. data/setup.rb +799 -574
  134. data/src/poparser.ry +6 -5
  135. data/test/gettext_runner.rb +3 -1
  136. data/test/gettext_test.rb +40 -24
  137. data/test/gettext_test_cgi.rb +60 -6
  138. data/test/gettext_test_locale.rb +136 -0
  139. data/test/gettext_test_parser.rb +12 -12
  140. data/test/locale/la/LC_MESSAGES/plural_error.mo +0 -0
  141. data/test/po/la/plural_error.po +21 -0
  142. data/test/test.bat +2 -0
  143. data/test/test.sh +2 -4
  144. data/test/test_rubyparser_n_.rb +64 -0
  145. metadata +24 -21
  146. data/ext/gettext/gettext/MANIFEST +0 -3
  147. data/ext/gettext/gettext/_locale-i386-mswin32.def +0 -2
  148. data/ext/gettext/gettext/_locale.exp +0 -0
  149. data/ext/gettext/gettext/_locale.lib +0 -0
  150. data/ext/gettext/gettext/_locale.obj +0 -0
  151. data/ext/gettext/gettext/_locale.so +0 -0
  152. data/ext/gettext/gettext/extconf.rb +0 -20
  153. data/ext/gettext/gettext/mkmf.log +0 -16
  154. data/lib/_locale.so +0 -0
  155. data/lib/gettext/locale_default.rb +0 -35
  156. data/po/it/messages.mo +0 -0
  157. data/samples/cgi/po/it/messages.mo +0 -0
@@ -10,7 +10,7 @@
10
10
  msgid ""
11
11
  msgstr ""
12
12
  "Project-Id-Version: gettext_plugin 1.1.0\n"
13
- "POT-Creation-Date: 2006-01-11 00:45+0900\n"
13
+ "POT-Creation-Date: 2006-01-19 16:49+0900\n"
14
14
  "PO-Revision-Date: 2005-12-19 21:44+0100\n"
15
15
  "Last-Translator: Menno Jonkers <ruby-gettext@jonkers.com>\n"
16
16
  "Language-Team: Dutch <ruby_gettext@jonkers.com>\n"
@@ -9,7 +9,7 @@
9
9
  msgid ""
10
10
  msgstr ""
11
11
  "Project-Id-Version: blog 1.1.0\n"
12
- "POT-Creation-Date: 2006-01-11 00:45+0900\n"
12
+ "POT-Creation-Date: 2006-01-19 16:49+0900\n"
13
13
  "PO-Revision-Date: 2005-12-17 10:12-0300\n"
14
14
  "Last-Translator: Joao Pedrosa <joaopedrosa@gmail.com>\n"
15
15
  "Language-Team: Portuguese(Brazil)\n"
@@ -9,7 +9,7 @@
9
9
  msgid ""
10
10
  msgstr ""
11
11
  "Project-Id-Version: gettext_plugin 1.1.0\n"
12
- "POT-Creation-Date: 2006-01-11 00:45+0900\n"
12
+ "POT-Creation-Date: 2006-01-19 16:49+0900\n"
13
13
  "PO-Revision-Date: 2005-12-17 10:12-0300\n"
14
14
  "Last-Translator: Joao Pedrosa <joaopedrosa@gmail.com>\n"
15
15
  "Language-Team: Portuguese(Brazil)\n"
data/setup.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #
2
2
  # setup.rb
3
3
  #
4
- # Copyright (c) 2000-2004 Minero Aoki
4
+ # Copyright (c) 2000-2005 Minero Aoki
5
5
  #
6
6
  # This program is free software.
7
7
  # You can distribute/modify this program under the terms of
@@ -22,175 +22,67 @@ unless File.respond_to?(:read) # Ruby 1.6
22
22
  end
23
23
  end
24
24
 
25
+ unless Errno.const_defined?(:ENOTEMPTY) # Windows?
26
+ module Errno
27
+ class ENOTEMPTY
28
+ # We do not raise this exception, implementation is not needed.
29
+ end
30
+ end
31
+ end
32
+
25
33
  def File.binread(fname)
26
34
  open(fname, 'rb') {|f|
27
35
  return f.read
28
36
  }
29
37
  end
30
38
 
31
- # for corrupted windows stat(2)
39
+ # for corrupted Windows' stat(2)
32
40
  def File.dir?(path)
33
41
  File.directory?((path[-1,1] == '/') ? path : path + '/')
34
42
  end
35
43
 
36
44
 
37
- class SetupError < StandardError; end
38
-
39
- def setup_rb_error(msg)
40
- raise SetupError, msg
41
- end
42
-
43
- #
44
- # Config
45
- #
46
-
47
- if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
48
- ARGV.delete(arg)
49
- require arg.split(/=/, 2)[1]
50
- $".push 'rbconfig.rb'
51
- else
52
- require 'rbconfig'
53
- end
54
-
55
- def multipackage_install?
56
- FileTest.directory?(File.dirname($0) + '/packages')
57
- end
58
-
59
-
60
- class ConfigItem
61
- def initialize(name, template, default, desc)
62
- @name = name.freeze
63
- @template = template
64
- @value = default
65
- @default = default.dup.freeze
66
- @description = desc
67
- end
68
-
69
- attr_reader :name
70
- attr_reader :description
71
-
72
- attr_accessor :default
73
- alias help_default default
74
-
75
- def help_opt
76
- "--#{@name}=#{@template}"
77
- end
78
-
79
- def value
80
- @value
81
- end
82
-
83
- def eval(table)
84
- @value.gsub(%r<\$([^/]+)>) { table[$1] }
85
- end
86
-
87
- def set(val)
88
- @value = check(val)
89
- end
90
-
91
- private
92
-
93
- def check(val)
94
- setup_rb_error "config: --#{name} requires argument" unless val
95
- val
96
- end
97
- end
98
-
99
- class BoolItem < ConfigItem
100
- def config_type
101
- 'bool'
102
- end
103
-
104
- def help_opt
105
- "--#{@name}"
106
- end
107
-
108
- private
45
+ class ConfigTable
109
46
 
110
- def check(val)
111
- return 'yes' unless val
112
- unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ val
113
- setup_rb_error "config: --#{@name} accepts only yes/no for argument"
114
- end
115
- (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no'
116
- end
117
- end
47
+ include Enumerable
118
48
 
119
- class PathItem < ConfigItem
120
- def config_type
121
- 'path'
49
+ def initialize(rbconfig)
50
+ @rbconfig = rbconfig
51
+ @items = []
52
+ @table = {}
53
+ # options
54
+ @install_prefix = nil
55
+ @config_opt = nil
56
+ @verbose = true
57
+ @no_harm = false
122
58
  end
123
59
 
124
- private
125
-
126
- def check(path)
127
- setup_rb_error "config: --#{@name} requires argument" unless path
128
- path[0,1] == '$' ? path : File.expand_path(path)
129
- end
130
- end
60
+ attr_accessor :install_prefix
61
+ attr_accessor :config_opt
131
62
 
132
- class ProgramItem < ConfigItem
133
- def config_type
134
- 'program'
135
- end
136
- end
63
+ attr_writer :verbose
137
64
 
138
- class SelectItem < ConfigItem
139
- def initialize(name, template, default, desc)
140
- super
141
- @ok = template.split('/')
142
- end
143
-
144
- def config_type
145
- 'select'
65
+ def verbose?
66
+ @verbose
146
67
  end
147
68
 
148
- private
69
+ attr_writer :no_harm
149
70
 
150
- def check(val)
151
- unless @ok.include?(val.strip)
152
- setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
153
- end
154
- val.strip
71
+ def no_harm?
72
+ @no_harm
155
73
  end
156
- end
157
74
 
158
- class PackageSelectionItem < ConfigItem
159
- def initialize(name, template, default, help_default, desc)
160
- super name, template, default, desc
161
- @help_default = help_default
75
+ def [](key)
76
+ lookup(key).resolve(self)
162
77
  end
163
78
 
164
- attr_reader :help_default
165
-
166
- def config_type
167
- 'package'
79
+ def []=(key, val)
80
+ lookup(key).set val
168
81
  end
169
82
 
170
- private
171
-
172
- def check(val)
173
- unless File.dir?("packages/#{val}")
174
- setup_rb_error "config: no such package: #{val}"
175
- end
176
- val
83
+ def names
84
+ @items.map {|i| i.name }
177
85
  end
178
- end
179
-
180
- class ConfigTable_class
181
-
182
- def initialize(items)
183
- @items = items
184
- @table = {}
185
- items.each do |i|
186
- @table[i.name] = i
187
- end
188
- ALIASES.each do |ali, name|
189
- @table[ali] = @table[name]
190
- end
191
- end
192
-
193
- include Enumerable
194
86
 
195
87
  def each(&block)
196
88
  @items.each(&block)
@@ -201,7 +93,7 @@ class ConfigTable_class
201
93
  end
202
94
 
203
95
  def lookup(name)
204
- @table[name] or raise ArgumentError, "no such config item: #{name}"
96
+ @table[name] or setup_rb_error "no such config item: #{name}"
205
97
  end
206
98
 
207
99
  def add(item)
@@ -216,24 +108,24 @@ class ConfigTable_class
216
108
  item
217
109
  end
218
110
 
219
- def new
220
- dup()
111
+ def load_script(path, inst = nil)
112
+ if File.file?(path)
113
+ MetaConfigEnvironment.new(self, inst).instance_eval File.read(path), path
114
+ end
221
115
  end
222
116
 
223
117
  def savefile
224
118
  '.config'
225
119
  end
226
120
 
227
- def load
121
+ def load_savefile
228
122
  begin
229
- t = dup()
230
123
  File.foreach(savefile()) do |line|
231
124
  k, v = *line.split(/=/, 2)
232
- t[k] = v.strip
125
+ self[k] = v.strip
233
126
  end
234
- t
235
127
  rescue Errno::ENOENT
236
- setup_rb_error $!.message + "#{File.basename($0)} config first"
128
+ setup_rb_error $!.message + "\n#{File.basename($0)} config first"
237
129
  end
238
130
  end
239
131
 
@@ -241,117 +133,151 @@ class ConfigTable_class
241
133
  @items.each {|i| i.value }
242
134
  File.open(savefile(), 'w') {|f|
243
135
  @items.each do |i|
244
- f.printf "%s=%s\n", i.name, i.value if i.value
136
+ f.printf "%s=%s\n", i.name, i.value if i.value? and i.value
245
137
  end
246
138
  }
247
139
  end
248
140
 
249
- def [](key)
250
- lookup(key).eval(self)
141
+ def load_standard_entries
142
+ standard_entries(@rbconfig).each do |ent|
143
+ add ent
144
+ end
251
145
  end
252
146
 
253
- def []=(key, val)
254
- lookup(key).set val
255
- end
147
+ def standard_entries(rbconfig)
148
+ c = rbconfig
149
+
150
+ rubypath = File.join(c['bindir'], c['ruby_install_name'] + c['EXEEXT'])
151
+
152
+ major = c['MAJOR'].to_i
153
+ minor = c['MINOR'].to_i
154
+ teeny = c['TEENY'].to_i
155
+ version = "#{major}.#{minor}"
156
+
157
+ # ruby ver. >= 1.4.4?
158
+ newpath_p = ((major >= 2) or
159
+ ((major == 1) and
160
+ ((minor >= 5) or
161
+ ((minor == 4) and (teeny >= 4)))))
162
+
163
+ if c['rubylibdir']
164
+ # V > 1.6.3
165
+ libruby = "#{c['prefix']}/lib/ruby"
166
+ librubyver = c['rubylibdir']
167
+ librubyverarch = c['archdir']
168
+ siteruby = c['sitedir']
169
+ siterubyver = c['sitelibdir']
170
+ siterubyverarch = c['sitearchdir']
171
+ elsif newpath_p
172
+ # 1.4.4 <= V <= 1.6.3
173
+ libruby = "#{c['prefix']}/lib/ruby"
174
+ librubyver = "#{c['prefix']}/lib/ruby/#{version}"
175
+ librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
176
+ siteruby = c['sitedir']
177
+ siterubyver = "$siteruby/#{version}"
178
+ siterubyverarch = "$siterubyver/#{c['arch']}"
179
+ else
180
+ # V < 1.4.4
181
+ libruby = "#{c['prefix']}/lib/ruby"
182
+ librubyver = "#{c['prefix']}/lib/ruby/#{version}"
183
+ librubyverarch = "#{c['prefix']}/lib/ruby/#{version}/#{c['arch']}"
184
+ siteruby = "#{c['prefix']}/lib/ruby/#{version}/site_ruby"
185
+ siterubyver = siteruby
186
+ siterubyverarch = "$siterubyver/#{c['arch']}"
187
+ end
188
+ parameterize = lambda {|path|
189
+ path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')
190
+ }
256
191
 
257
- end
192
+ if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
193
+ makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
194
+ else
195
+ makeprog = 'make'
196
+ end
258
197
 
259
- c = ::Config::CONFIG
260
-
261
- rubypath = c['bindir'] + '/' + c['ruby_install_name']
262
-
263
- major = c['MAJOR'].to_i
264
- minor = c['MINOR'].to_i
265
- teeny = c['TEENY'].to_i
266
- version = "#{major}.#{minor}"
267
-
268
- # ruby ver. >= 1.4.4?
269
- newpath_p = ((major >= 2) or
270
- ((major == 1) and
271
- ((minor >= 5) or
272
- ((minor == 4) and (teeny >= 4)))))
273
-
274
- if c['rubylibdir']
275
- # V < 1.6.3
276
- _stdruby = c['rubylibdir']
277
- _siteruby = c['sitedir']
278
- _siterubyver = c['sitelibdir']
279
- _siterubyverarch = c['sitearchdir']
280
- elsif newpath_p
281
- # 1.4.4 <= V <= 1.6.3
282
- _stdruby = "$prefix/lib/ruby/#{version}"
283
- _siteruby = c['sitedir']
284
- _siterubyver = "$siteruby/#{version}"
285
- _siterubyverarch = "$siterubyver/#{c['arch']}"
286
- else
287
- # V < 1.4.4
288
- _stdruby = "$prefix/lib/ruby/#{version}"
289
- _siteruby = "$prefix/lib/ruby/#{version}/site_ruby"
290
- _siterubyver = _siteruby
291
- _siterubyverarch = "$siterubyver/#{c['arch']}"
292
- end
293
- libdir = '-* dummy libdir *-'
294
- stdruby = '-* dummy rubylibdir *-'
295
- siteruby = '-* dummy site_ruby *-'
296
- siterubyver = '-* dummy site_ruby version *-'
297
- parameterize = lambda {|path|
298
- path.sub(/\A#{Regexp.quote(c['prefix'])}/, '$prefix')\
299
- .sub(/\A#{Regexp.quote(libdir)}/, '$libdir')\
300
- .sub(/\A#{Regexp.quote(stdruby)}/, '$stdruby')\
301
- .sub(/\A#{Regexp.quote(siteruby)}/, '$siteruby')\
302
- .sub(/\A#{Regexp.quote(siterubyver)}/, '$siterubyver')
303
- }
304
- libdir = parameterize.call(c['libdir'])
305
- stdruby = parameterize.call(_stdruby)
306
- siteruby = parameterize.call(_siteruby)
307
- siterubyver = parameterize.call(_siterubyver)
308
- siterubyverarch = parameterize.call(_siterubyverarch)
309
-
310
- if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
311
- makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
312
- else
313
- makeprog = 'make'
314
- end
198
+ [
199
+ ExecItem.new('installdirs', 'std/site/home',
200
+ 'std: install under libruby; site: install under site_ruby; home: install under $HOME')\
201
+ {|val, table|
202
+ case val
203
+ when 'std'
204
+ table['rbdir'] = '$librubyver'
205
+ table['sodir'] = '$librubyverarch'
206
+ when 'site'
207
+ table['rbdir'] = '$siterubyver'
208
+ table['sodir'] = '$siterubyverarch'
209
+ when 'home'
210
+ setup_rb_error '$HOME was not set' unless ENV['HOME']
211
+ table['prefix'] = ENV['HOME']
212
+ table['rbdir'] = '$libdir/ruby'
213
+ table['sodir'] = '$libdir/ruby'
214
+ end
215
+ },
216
+ PathItem.new('prefix', 'path', c['prefix'],
217
+ 'path prefix of target environment'),
218
+ PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
219
+ 'the directory for commands'),
220
+ PathItem.new('libdir', 'path', parameterize.call(c['libdir']),
221
+ 'the directory for libraries'),
222
+ PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
223
+ 'the directory for shared data'),
224
+ PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
225
+ 'the directory for man pages'),
226
+ PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
227
+ 'the directory for system configuration files'),
228
+ PathItem.new('localstatedir', 'path', parameterize.call(c['localstatedir']),
229
+ 'the directory for local state data'),
230
+ PathItem.new('libruby', 'path', libruby,
231
+ 'the directory for ruby libraries'),
232
+ PathItem.new('librubyver', 'path', librubyver,
233
+ 'the directory for standard ruby libraries'),
234
+ PathItem.new('librubyverarch', 'path', librubyverarch,
235
+ 'the directory for standard ruby extensions'),
236
+ PathItem.new('siteruby', 'path', siteruby,
237
+ 'the directory for version-independent aux ruby libraries'),
238
+ PathItem.new('siterubyver', 'path', siterubyver,
239
+ 'the directory for aux ruby libraries'),
240
+ PathItem.new('siterubyverarch', 'path', siterubyverarch,
241
+ 'the directory for aux ruby binaries'),
242
+ PathItem.new('rbdir', 'path', '$siterubyver',
243
+ 'the directory for ruby scripts'),
244
+ PathItem.new('sodir', 'path', '$siterubyverarch',
245
+ 'the directory for ruby extentions'),
246
+ PathItem.new('rubypath', 'path', rubypath,
247
+ 'the path to set to #! line'),
248
+ ProgramItem.new('rubyprog', 'name', rubypath,
249
+ 'the ruby program using for installation'),
250
+ ProgramItem.new('makeprog', 'name', makeprog,
251
+ 'the make program to compile ruby extentions'),
252
+ SelectItem.new('shebang', 'all/ruby/never', 'ruby',
253
+ 'shebang line (#!) editing mode'),
254
+ BoolItem.new('without-ext', 'yes/no', 'no',
255
+ 'does not compile/install ruby extentions')
256
+ ]
257
+ end
258
+ private :standard_entries
259
+
260
+ def load_multipackage_entries
261
+ multipackage_entries().each do |ent|
262
+ add ent
263
+ end
264
+ end
265
+
266
+ def multipackage_entries
267
+ [
268
+ PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
269
+ 'package names that you want to install'),
270
+ PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
271
+ 'package names that you do not want to install')
272
+ ]
273
+ end
274
+ private :multipackage_entries
315
275
 
316
- common_conf = [
317
- PathItem.new('prefix', 'path', c['prefix'],
318
- 'path prefix of target environment'),
319
- PathItem.new('bindir', 'path', parameterize.call(c['bindir']),
320
- 'the directory for commands'),
321
- PathItem.new('libdir', 'path', libdir,
322
- 'the directory for libraries'),
323
- PathItem.new('datadir', 'path', parameterize.call(c['datadir']),
324
- 'the directory for shared data'),
325
- PathItem.new('mandir', 'path', parameterize.call(c['mandir']),
326
- 'the directory for man pages'),
327
- PathItem.new('sysconfdir', 'path', parameterize.call(c['sysconfdir']),
328
- 'the directory for man pages'),
329
- PathItem.new('stdruby', 'path', stdruby,
330
- 'the directory for standard ruby libraries'),
331
- PathItem.new('siteruby', 'path', siteruby,
332
- 'the directory for version-independent aux ruby libraries'),
333
- PathItem.new('siterubyver', 'path', siterubyver,
334
- 'the directory for aux ruby libraries'),
335
- PathItem.new('siterubyverarch', 'path', siterubyverarch,
336
- 'the directory for aux ruby binaries'),
337
- PathItem.new('rbdir', 'path', '$siterubyver',
338
- 'the directory for ruby scripts'),
339
- PathItem.new('sodir', 'path', '$siterubyverarch',
340
- 'the directory for ruby extentions'),
341
- PathItem.new('rubypath', 'path', rubypath,
342
- 'the path to set to #! line'),
343
- ProgramItem.new('rubyprog', 'name', rubypath,
344
- 'the ruby program using for installation'),
345
- ProgramItem.new('makeprog', 'name', makeprog,
346
- 'the make program to compile ruby extentions'),
347
- SelectItem.new('shebang', 'all/ruby/never', 'ruby',
348
- 'shebang line (#!) editing mode'),
349
- BoolItem.new('without-ext', 'yes/no', 'no',
350
- 'does not compile/install ruby extentions')
351
- ]
352
- class ConfigTable_class # open again
353
276
  ALIASES = {
354
- 'std-ruby' => 'stdruby',
277
+ 'std-ruby' => 'librubyver',
278
+ 'stdruby' => 'librubyver',
279
+ 'rubylibdir' => 'librubyver',
280
+ 'archdir' => 'librubyverarch',
355
281
  'site-ruby-common' => 'siteruby', # For backward compatibility
356
282
  'site-ruby' => 'siterubyver', # For backward compatibility
357
283
  'bin-dir' => 'bindir',
@@ -365,78 +291,248 @@ class ConfigTable_class # open again
365
291
  'make-prog' => 'makeprog',
366
292
  'make' => 'makeprog'
367
293
  }
368
- end
369
- multipackage_conf = [
370
- PackageSelectionItem.new('with', 'name,name...', '', 'ALL',
371
- 'package names that you want to install'),
372
- PackageSelectionItem.new('without', 'name,name...', '', 'NONE',
373
- 'package names that you do not want to install')
374
- ]
375
- if multipackage_install?
376
- ConfigTable = ConfigTable_class.new(common_conf + multipackage_conf)
377
- else
378
- ConfigTable = ConfigTable_class.new(common_conf)
379
- end
380
-
381
294
 
382
- module MetaConfigAPI
383
-
384
- def eval_file_ifexist(fname)
385
- instance_eval File.read(fname), fname, 1 if File.file?(fname)
295
+ def fixup
296
+ ALIASES.each do |ali, name|
297
+ @table[ali] = @table[name]
298
+ end
299
+ @items.freeze
300
+ @table.freeze
301
+ @options_re = /\A--(#{@table.keys.join('|')})(?:=(.*))?\z/
386
302
  end
387
303
 
388
- def config_names
389
- ConfigTable.map {|i| i.name }
304
+ def parse_opt(opt)
305
+ m = @options_re.match(opt) or setup_rb_error "config: unknown option #{opt}"
306
+ m.to_a[1,2]
390
307
  end
391
308
 
392
- def config?(name)
393
- ConfigTable.key?(name)
309
+ def dllext
310
+ @rbconfig['DLEXT']
394
311
  end
395
312
 
396
- def bool_config?(name)
397
- ConfigTable.lookup(name).config_type == 'bool'
313
+ def value_config?(name)
314
+ lookup(name).value?
398
315
  end
399
316
 
400
- def path_config?(name)
401
- ConfigTable.lookup(name).config_type == 'path'
402
- end
317
+ class Item
318
+ def initialize(name, template, default, desc)
319
+ @name = name.freeze
320
+ @template = template
321
+ @value = default
322
+ @default = default
323
+ @description = desc
324
+ end
403
325
 
404
- def value_config?(name)
405
- case ConfigTable.lookup(name).config_type
406
- when 'bool', 'path'
326
+ attr_reader :name
327
+ attr_reader :description
328
+
329
+ attr_accessor :default
330
+ alias help_default default
331
+
332
+ def help_opt
333
+ "--#{@name}=#{@template}"
334
+ end
335
+
336
+ def value?
407
337
  true
408
- else
409
- false
338
+ end
339
+
340
+ def value
341
+ @value
342
+ end
343
+
344
+ def resolve(table)
345
+ @value.gsub(%r<\$([^/]+)>) { table[$1] }
346
+ end
347
+
348
+ def set(val)
349
+ @value = check(val)
350
+ end
351
+
352
+ private
353
+
354
+ def check(val)
355
+ setup_rb_error "config: --#{name} requires argument" unless val
356
+ val
410
357
  end
411
358
  end
412
359
 
413
- def add_config(item)
414
- ConfigTable.add item
360
+ class BoolItem < Item
361
+ def config_type
362
+ 'bool'
363
+ end
364
+
365
+ def help_opt
366
+ "--#{@name}"
367
+ end
368
+
369
+ private
370
+
371
+ def check(val)
372
+ return 'yes' unless val
373
+ case val
374
+ when /\Ay(es)?\z/i, /\At(rue)?\z/i then 'yes'
375
+ when /\An(o)?\z/i, /\Af(alse)\z/i then 'no'
376
+ else
377
+ setup_rb_error "config: --#{@name} accepts only yes/no for argument"
378
+ end
379
+ end
415
380
  end
416
381
 
417
- def add_bool_config(name, default, desc)
418
- ConfigTable.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
382
+ class PathItem < Item
383
+ def config_type
384
+ 'path'
385
+ end
386
+
387
+ private
388
+
389
+ def check(path)
390
+ setup_rb_error "config: --#{@name} requires argument" unless path
391
+ path[0,1] == '$' ? path : File.expand_path(path)
392
+ end
419
393
  end
420
394
 
421
- def add_path_config(name, default, desc)
422
- ConfigTable.add PathItem.new(name, 'path', default, desc)
395
+ class ProgramItem < Item
396
+ def config_type
397
+ 'program'
398
+ end
423
399
  end
424
400
 
425
- def set_config_default(name, default)
426
- ConfigTable.lookup(name).default = default
401
+ class SelectItem < Item
402
+ def initialize(name, selection, default, desc)
403
+ super
404
+ @ok = selection.split('/')
405
+ end
406
+
407
+ def config_type
408
+ 'select'
409
+ end
410
+
411
+ private
412
+
413
+ def check(val)
414
+ unless @ok.include?(val.strip)
415
+ setup_rb_error "config: use --#{@name}=#{@template} (#{val})"
416
+ end
417
+ val.strip
418
+ end
427
419
  end
428
420
 
429
- def remove_config(name)
430
- ConfigTable.remove(name)
421
+ class ExecItem < Item
422
+ def initialize(name, selection, desc, &block)
423
+ super name, selection, nil, desc
424
+ @ok = selection.split('/')
425
+ @action = block
426
+ end
427
+
428
+ def config_type
429
+ 'exec'
430
+ end
431
+
432
+ def value?
433
+ false
434
+ end
435
+
436
+ def resolve(table)
437
+ setup_rb_error "$#{name()} wrongly used as option value"
438
+ end
439
+
440
+ undef set
441
+
442
+ def evaluate(val, table)
443
+ v = val.strip.downcase
444
+ unless @ok.include?(v)
445
+ setup_rb_error "invalid option --#{@name}=#{val} (use #{@template})"
446
+ end
447
+ @action.call v, table
448
+ end
431
449
  end
432
450
 
433
- end
451
+ class PackageSelectionItem < Item
452
+ def initialize(name, template, default, help_default, desc)
453
+ super name, template, default, desc
454
+ @help_default = help_default
455
+ end
434
456
 
457
+ attr_reader :help_default
435
458
 
436
- #
437
- # File Operations
438
- #
459
+ def config_type
460
+ 'package'
461
+ end
462
+
463
+ private
464
+
465
+ def check(val)
466
+ unless File.dir?("packages/#{val}")
467
+ setup_rb_error "config: no such package: #{val}"
468
+ end
469
+ val
470
+ end
471
+ end
472
+
473
+ class MetaConfigEnvironment
474
+ def initialize(config, installer)
475
+ @config = config
476
+ @installer = installer
477
+ end
478
+
479
+ def config_names
480
+ @config.names
481
+ end
482
+
483
+ def config?(name)
484
+ @config.key?(name)
485
+ end
486
+
487
+ def bool_config?(name)
488
+ @config.lookup(name).config_type == 'bool'
489
+ end
490
+
491
+ def path_config?(name)
492
+ @config.lookup(name).config_type == 'path'
493
+ end
494
+
495
+ def value_config?(name)
496
+ @config.lookup(name).config_type != 'exec'
497
+ end
498
+
499
+ def add_config(item)
500
+ @config.add item
501
+ end
502
+
503
+ def add_bool_config(name, default, desc)
504
+ @config.add BoolItem.new(name, 'yes/no', default ? 'yes' : 'no', desc)
505
+ end
439
506
 
507
+ def add_path_config(name, default, desc)
508
+ @config.add PathItem.new(name, 'path', default, desc)
509
+ end
510
+
511
+ def set_config_default(name, default)
512
+ @config.lookup(name).default = default
513
+ end
514
+
515
+ def remove_config(name)
516
+ @config.remove(name)
517
+ end
518
+
519
+ # For only multipackage
520
+ def packages
521
+ raise '[setup.rb fatal] multi-package metaconfig API packages() called for single-package; contact application package vendor' unless @installer
522
+ @installer.packages
523
+ end
524
+
525
+ # For only multipackage
526
+ def declare_packages(list)
527
+ raise '[setup.rb fatal] multi-package metaconfig API declare_packages() called for single-package; contact application package vendor' unless @installer
528
+ @installer.packages = list
529
+ end
530
+ end
531
+
532
+ end # class ConfigTable
533
+
534
+
535
+ # This module requires: #verbose?, #no_harm?
440
536
  module FileOperations
441
537
 
442
538
  def mkdir_p(dirname, prefix = nil)
@@ -444,7 +540,7 @@ module FileOperations
444
540
  $stderr.puts "mkdir -p #{dirname}" if verbose?
445
541
  return if no_harm?
446
542
 
447
- # does not check '/'... it's too abnormal case
543
+ # Does not check '/', it's too abnormal.
448
544
  dirs = File.expand_path(dirname).split(%r<(?=/)>)
449
545
  if /\A[a-z]:\z/i =~ dirs[0]
450
546
  disk = dirs.shift
@@ -456,49 +552,73 @@ module FileOperations
456
552
  end
457
553
  end
458
554
 
459
- def rm_f(fname)
460
- $stderr.puts "rm -f #{fname}" if verbose?
555
+ def rm_f(path)
556
+ $stderr.puts "rm -f #{path}" if verbose?
461
557
  return if no_harm?
462
-
463
- if File.exist?(fname) or File.symlink?(fname)
464
- File.chmod 0777, fname
465
- File.unlink fname
466
- end
558
+ force_remove_file path
467
559
  end
468
560
 
469
- def rm_rf(dn)
470
- $stderr.puts "rm -rf #{dn}" if verbose?
561
+ def rm_rf(path)
562
+ $stderr.puts "rm -rf #{path}" if verbose?
471
563
  return if no_harm?
564
+ remove_tree path
565
+ end
566
+
567
+ def remove_tree(path)
568
+ if File.symlink?(path)
569
+ remove_file path
570
+ elsif File.dir?(path)
571
+ remove_tree0 path
572
+ else
573
+ force_remove_file path
574
+ end
575
+ end
472
576
 
473
- Dir.chdir dn
474
- Dir.foreach('.') do |fn|
475
- next if fn == '.'
476
- next if fn == '..'
477
- if File.dir?(fn)
478
- verbose_off {
479
- rm_rf fn
480
- }
577
+ def remove_tree0(path)
578
+ Dir.foreach(path) do |ent|
579
+ next if ent == '.'
580
+ next if ent == '..'
581
+ entpath = "#{path}/#{ent}"
582
+ if File.symlink?(entpath)
583
+ remove_file entpath
584
+ elsif File.dir?(entpath)
585
+ remove_tree0 entpath
481
586
  else
482
- verbose_off {
483
- rm_f fn
484
- }
587
+ force_remove_file entpath
485
588
  end
486
589
  end
487
- Dir.chdir '..'
488
- Dir.rmdir dn
590
+ begin
591
+ Dir.rmdir path
592
+ rescue Errno::ENOTEMPTY
593
+ # directory may not be empty
594
+ end
489
595
  end
490
596
 
491
597
  def move_file(src, dest)
492
- File.unlink dest if File.exist?(dest)
598
+ force_remove_file dest
493
599
  begin
494
600
  File.rename src, dest
495
601
  rescue
496
- File.open(dest, 'wb') {|f| f.write File.binread(src) }
602
+ File.open(dest, 'wb') {|f|
603
+ f.write File.binread(src)
604
+ }
497
605
  File.chmod File.stat(src).mode, dest
498
606
  File.unlink src
499
607
  end
500
608
  end
501
609
 
610
+ def force_remove_file(path)
611
+ begin
612
+ remove_file path
613
+ rescue
614
+ end
615
+ end
616
+
617
+ def remove_file(path)
618
+ File.chmod 0777, path
619
+ File.unlink path
620
+ end
621
+
502
622
  def install(from, dest, mode, prefix = nil)
503
623
  $stderr.puts "install #{from} #{dest}" if verbose?
504
624
  return if no_harm?
@@ -530,66 +650,42 @@ module FileOperations
530
650
  new_content != File.binread(path)
531
651
  end
532
652
 
533
- def command(str)
534
- $stderr.puts str if verbose?
535
- system str or raise RuntimeError, "'system #{str}' failed"
653
+ def command(*args)
654
+ $stderr.puts args.join(' ') if verbose?
655
+ system(*args) or raise RuntimeError,
656
+ "system(#{args.map{|a| a.inspect }.join(' ')}) failed"
536
657
  end
537
658
 
538
- def ruby(str)
539
- command config('rubyprog') + ' ' + str
659
+ def ruby(*args)
660
+ command config('rubyprog'), *args
540
661
  end
541
662
 
542
- def make(task = '')
543
- command config('makeprog') + ' ' + task
663
+ def make(task = nil)
664
+ command(*[config('makeprog'), task].compact)
544
665
  end
545
666
 
546
667
  def extdir?(dir)
547
- File.exist?(dir + '/MANIFEST')
668
+ File.exist?("#{dir}/MANIFEST") or File.exist?("#{dir}/extconf.rb")
548
669
  end
549
670
 
550
- def all_files_in(dirname)
551
- Dir.open(dirname) {|d|
552
- return d.select {|ent| File.file?("#{dirname}/#{ent}") }
671
+ def files_of(dir)
672
+ Dir.open(dir) {|d|
673
+ return d.select {|ent| File.file?("#{dir}/#{ent}") }
553
674
  }
554
675
  end
555
676
 
556
- REJECT_DIRS = %w(
557
- CVS SCCS RCS CVS.adm .svn
558
- )
677
+ DIR_REJECT = %w( . .. CVS SCCS RCS CVS.adm .svn )
559
678
 
560
- def all_dirs_in(dirname)
561
- Dir.open(dirname) {|d|
562
- return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS
679
+ def directories_of(dir)
680
+ Dir.open(dir) {|d|
681
+ return d.select {|ent| File.dir?("#{dir}/#{ent}") } - DIR_REJECT
563
682
  }
564
683
  end
565
684
 
566
685
  end
567
686
 
568
687
 
569
- #
570
- # Main Installer
571
- #
572
-
573
- module HookUtils
574
-
575
- def run_hook(name)
576
- try_run_hook "#{curr_srcdir()}/#{name}" or
577
- try_run_hook "#{curr_srcdir()}/#{name}.rb"
578
- end
579
-
580
- def try_run_hook(fname)
581
- return false unless File.file?(fname)
582
- begin
583
- instance_eval File.read(fname), fname, 1
584
- rescue
585
- setup_rb_error "hook #{fname} failed:\n" + $!.message
586
- end
587
- true
588
- end
589
-
590
- end
591
-
592
-
688
+ # This module requires: #srcdir_root, #objdir_root, #relpath
593
689
  module HookScriptAPI
594
690
 
595
691
  def get_config(key)
@@ -598,6 +694,7 @@ module HookScriptAPI
598
694
 
599
695
  alias config get_config
600
696
 
697
+ # obsolete: use metaconfig to change configuration
601
698
  def set_config(key, val)
602
699
  @config[key] = val
603
700
  end
@@ -606,10 +703,6 @@ module HookScriptAPI
606
703
  # srcdir/objdir (works only in the package directory)
607
704
  #
608
705
 
609
- #abstract srcdir_root
610
- #abstract objdir_root
611
- #abstract relpath
612
-
613
706
  def curr_srcdir
614
707
  "#{srcdir_root()}/#{relpath()}"
615
708
  end
@@ -631,7 +724,7 @@ module HookScriptAPI
631
724
  end
632
725
 
633
726
  def srcfile?(path)
634
- File.file? srcfile(path)
727
+ File.file?(srcfile(path))
635
728
  end
636
729
 
637
730
  def srcentries(path = '.')
@@ -657,8 +750,8 @@ end
657
750
 
658
751
  class ToplevelInstaller
659
752
 
660
- Version = '3.3.1'
661
- Copyright = 'Copyright (c) 2000-2004 Minero Aoki'
753
+ Version = '3.4.1'
754
+ Copyright = 'Copyright (c) 2000-2005 Minero Aoki'
662
755
 
663
756
  TASKS = [
664
757
  [ 'all', 'do config, setup, then install' ],
@@ -666,27 +759,44 @@ class ToplevelInstaller
666
759
  [ 'show', 'shows current configuration' ],
667
760
  [ 'setup', 'compiles ruby extentions and others' ],
668
761
  [ 'install', 'installs files' ],
762
+ [ 'test', 'run all tests in test/' ],
669
763
  [ 'clean', "does `make clean' for each extention" ],
670
764
  [ 'distclean',"does `make distclean' for each extention" ]
671
765
  ]
672
766
 
673
767
  def ToplevelInstaller.invoke
674
- instance().invoke
768
+ config = ConfigTable.new(load_rbconfig())
769
+ config.load_standard_entries
770
+ config.load_multipackage_entries if multipackage?
771
+ config.fixup
772
+ klass = (multipackage?() ? ToplevelInstallerMulti : ToplevelInstaller)
773
+ klass.new(File.dirname($0), config).invoke
675
774
  end
676
775
 
677
- @singleton = nil
678
-
679
- def ToplevelInstaller.instance
680
- @singleton ||= new(File.dirname($0))
681
- @singleton
776
+ def ToplevelInstaller.multipackage?
777
+ File.dir?(File.dirname($0) + '/packages')
682
778
  end
683
779
 
684
- include MetaConfigAPI
780
+ def ToplevelInstaller.load_rbconfig
781
+ if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
782
+ ARGV.delete(arg)
783
+ load File.expand_path(arg.split(/=/, 2)[1])
784
+ $".push 'rbconfig.rb'
785
+ else
786
+ require 'rbconfig'
787
+ end
788
+ ::Config::CONFIG
789
+ end
685
790
 
686
- def initialize(ardir_root)
687
- @config = nil
688
- @options = { 'verbose' => true }
791
+ def initialize(ardir_root, config)
689
792
  @ardir = File.expand_path(ardir_root)
793
+ @config = config
794
+ # cache
795
+ @valid_task_re = nil
796
+ end
797
+
798
+ def config(key)
799
+ @config[key]
690
800
  end
691
801
 
692
802
  def inspect
@@ -697,14 +807,20 @@ class ToplevelInstaller
697
807
  run_metaconfigs
698
808
  case task = parsearg_global()
699
809
  when nil, 'all'
700
- @config = load_config('config')
701
810
  parsearg_config
702
811
  init_installers
703
812
  exec_config
704
813
  exec_setup
705
814
  exec_install
706
815
  else
707
- @config = load_config(task)
816
+ case task
817
+ when 'config', 'test'
818
+ ;
819
+ when 'clean', 'distclean'
820
+ @config.load_savefile if File.exist?(@config.savefile)
821
+ else
822
+ @config.load_savefile
823
+ end
708
824
  __send__ "parsearg_#{task}"
709
825
  init_installers
710
826
  __send__ "exec_#{task}"
@@ -712,25 +828,11 @@ class ToplevelInstaller
712
828
  end
713
829
 
714
830
  def run_metaconfigs
715
- eval_file_ifexist "#{@ardir}/metaconfig"
716
- end
717
-
718
- def load_config(task)
719
- case task
720
- when 'config'
721
- ConfigTable.new
722
- when 'clean', 'distclean'
723
- if File.exist?(ConfigTable.savefile)
724
- then ConfigTable.load
725
- else ConfigTable.new
726
- end
727
- else
728
- ConfigTable.load
729
- end
831
+ @config.load_script "#{@ardir}/metaconfig"
730
832
  end
731
833
 
732
834
  def init_installers
733
- @installer = Installer.new(@config, @options, @ardir, File.expand_path('.'))
835
+ @installer = Installer.new(@config, @ardir, File.expand_path('.'))
734
836
  end
735
837
 
736
838
  #
@@ -754,78 +856,89 @@ class ToplevelInstaller
754
856
  #
755
857
 
756
858
  def parsearg_global
757
- valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/
758
-
759
859
  while arg = ARGV.shift
760
860
  case arg
761
861
  when /\A\w+\z/
762
- setup_rb_error "invalid task: #{arg}" unless valid_task =~ arg
862
+ setup_rb_error "invalid task: #{arg}" unless valid_task?(arg)
763
863
  return arg
764
-
765
864
  when '-q', '--quiet'
766
- @options['verbose'] = false
767
-
768
- when '--verbose'
769
- @options['verbose'] = true
770
-
771
- when '-h', '--help'
865
+ @config.verbose = false
866
+ when '--verbose'
867
+ @config.verbose = true
868
+ when '--help'
772
869
  print_usage $stdout
773
870
  exit 0
774
-
775
- when '-v', '--version'
871
+ when '--version'
776
872
  puts "#{File.basename($0)} version #{Version}"
777
873
  exit 0
778
-
779
874
  when '--copyright'
780
875
  puts Copyright
781
876
  exit 0
782
-
783
877
  else
784
878
  setup_rb_error "unknown global option '#{arg}'"
785
879
  end
786
880
  end
787
-
788
881
  nil
789
882
  end
790
883
 
884
+ def valid_task?(t)
885
+ valid_task_re() =~ t
886
+ end
887
+
888
+ def valid_task_re
889
+ @valid_task_re ||= /\A(?:#{TASKS.map {|task,desc| task }.join('|')})\z/
890
+ end
791
891
 
792
892
  def parsearg_no_options
793
893
  unless ARGV.empty?
794
- setup_rb_error "#{task}: unknown options: #{ARGV.join ' '}"
894
+ task = caller(0).first.slice(%r<`parsearg_(\w+)'>, 1)
895
+ setup_rb_error "#{task}: unknown options: #{ARGV.join(' ')}"
795
896
  end
796
897
  end
797
898
 
798
899
  alias parsearg_show parsearg_no_options
799
900
  alias parsearg_setup parsearg_no_options
901
+ alias parsearg_test parsearg_no_options
800
902
  alias parsearg_clean parsearg_no_options
801
903
  alias parsearg_distclean parsearg_no_options
802
904
 
803
905
  def parsearg_config
804
- re = /\A--(#{ConfigTable.map {|i| i.name }.join('|')})(?:=(.*))?\z/
805
- @options['config-opt'] = []
806
-
906
+ evalopt = []
907
+ set = []
908
+ @config.config_opt = []
807
909
  while i = ARGV.shift
808
910
  if /\A--?\z/ =~ i
809
- @options['config-opt'] = ARGV.dup
911
+ @config.config_opt = ARGV.dup
810
912
  break
811
913
  end
812
- m = re.match(i) or setup_rb_error "config: unknown option #{i}"
813
- name, value = *m.to_a[1,2]
814
- @config[name] = value
914
+ name, value = *@config.parse_opt(i)
915
+ if @config.value_config?(name)
916
+ @config[name] = value
917
+ else
918
+ evalopt.push [name, value]
919
+ end
920
+ set.push name
921
+ end
922
+ evalopt.each do |name, value|
923
+ @config.lookup(name).evaluate value, @config
924
+ end
925
+ # Check if configuration is valid
926
+ set.each do |n|
927
+ @config[n] if @config.value_config?(n)
815
928
  end
816
929
  end
817
930
 
818
931
  def parsearg_install
819
- @options['no-harm'] = false
820
- @options['install-prefix'] = ''
932
+ @config.no_harm = false
933
+ @config.install_prefix = ''
821
934
  while a = ARGV.shift
822
935
  case a
823
- when /\A--no-harm\z/
824
- @options['no-harm'] = true
825
- when /\A--prefix=(.*)\z/
826
- path = $1
936
+ when '--no-harm'
937
+ @config.no_harm = true
938
+ when /\A--prefix=/
939
+ path = a.split(/=/, 2)[1]
827
940
  path = File.expand_path(path) unless path[0,1] == '/'
828
- @options['install-prefix'] = path
941
+ @config.install_prefix = path
829
942
  else
830
943
  setup_rb_error "install: unknown option #{a}"
831
944
  end
@@ -847,8 +960,8 @@ class ToplevelInstaller
847
960
  out.puts 'Global options:'
848
961
  out.printf fmt, '-q,--quiet', 'suppress message outputs'
849
962
  out.printf fmt, ' --verbose', 'output messages verbosely'
850
- out.printf fmt, '-h,--help', 'print this message'
851
- out.printf fmt, '-v,--version', 'print version and quit'
963
+ out.printf fmt, ' --help', 'print this message'
964
+ out.printf fmt, ' --version', 'print version and quit'
852
965
  out.printf fmt, ' --copyright', 'print copyright and quit'
853
966
  out.puts
854
967
  out.puts 'Tasks:'
@@ -859,14 +972,14 @@ class ToplevelInstaller
859
972
  fmt = " %-24s %s [%s]\n"
860
973
  out.puts
861
974
  out.puts 'Options for CONFIG or ALL:'
862
- ConfigTable.each do |item|
975
+ @config.each do |item|
863
976
  out.printf fmt, item.help_opt, item.description, item.help_default
864
977
  end
865
978
  out.printf fmt, '--rbconfig=path', 'rbconfig.rb to load',"running ruby's"
866
979
  out.puts
867
980
  out.puts 'Options for INSTALL:'
868
981
  out.printf fmt, '--no-harm', 'only display what to do if given', 'off'
869
- out.printf fmt, '--prefix=path', 'install path prefix', '$prefix'
982
+ out.printf fmt, '--prefix=path', 'install path prefix', ''
870
983
  out.puts
871
984
  end
872
985
 
@@ -887,9 +1000,13 @@ class ToplevelInstaller
887
1000
  @installer.exec_install
888
1001
  end
889
1002
 
1003
+ def exec_test
1004
+ @installer.exec_test
1005
+ end
1006
+
890
1007
  def exec_show
891
- ConfigTable.each do |i|
892
- printf "%-20s %s\n", i.name, i.value
1008
+ @config.each do |i|
1009
+ printf "%-20s %s\n", i.name, i.value if i.value?
893
1010
  end
894
1011
  end
895
1012
 
@@ -901,36 +1018,45 @@ class ToplevelInstaller
901
1018
  @installer.exec_distclean
902
1019
  end
903
1020
 
904
- end
1021
+ end # class ToplevelInstaller
905
1022
 
906
1023
 
907
1024
  class ToplevelInstallerMulti < ToplevelInstaller
908
1025
 
909
- include HookUtils
910
- include HookScriptAPI
911
1026
  include FileOperations
912
1027
 
913
- def initialize(ardir)
1028
+ def initialize(ardir_root, config)
914
1029
  super
915
- @packages = all_dirs_in("#{@ardir}/packages")
1030
+ @packages = directories_of("#{@ardir}/packages")
916
1031
  raise 'no package exists' if @packages.empty?
1032
+ @root_installer = Installer.new(@config, @ardir, File.expand_path('.'))
917
1033
  end
918
1034
 
919
1035
  def run_metaconfigs
920
- eval_file_ifexist "#{@ardir}/metaconfig"
1036
+ @config.load_script "#{@ardir}/metaconfig", self
921
1037
  @packages.each do |name|
922
- eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig"
1038
+ @config.load_script "#{@ardir}/packages/#{name}/metaconfig"
923
1039
  end
924
1040
  end
925
1041
 
1042
+ attr_reader :packages
1043
+
1044
+ def packages=(list)
1045
+ raise 'package list is empty' if list.empty?
1046
+ list.each do |name|
1047
+ raise "directory packages/#{name} does not exist"\
1048
+ unless File.dir?("#{@ardir}/packages/#{name}")
1049
+ end
1050
+ @packages = list
1051
+ end
1052
+
926
1053
  def init_installers
927
1054
  @installers = {}
928
1055
  @packages.each do |pack|
929
- @installers[pack] = Installer.new(@config, @options,
1056
+ @installers[pack] = Installer.new(@config,
930
1057
  "#{@ardir}/packages/#{pack}",
931
1058
  "packages/#{pack}")
932
1059
  end
933
-
934
1060
  with = extract_selection(config('with'))
935
1061
  without = extract_selection(config('without'))
936
1062
  @selected = @installers.keys.select {|name|
@@ -954,21 +1080,6 @@ class ToplevelInstallerMulti < ToplevelInstaller
954
1080
  f.puts
955
1081
  end
956
1082
 
957
- #
958
- # multi-package metaconfig API
959
- #
960
-
961
- attr_reader :packages
962
-
963
- def declare_packages(list)
964
- raise 'package list is empty' if list.empty?
965
- list.each do |name|
966
- raise "directory packages/#{name} does not exist"\
967
- unless File.dir?("#{@ardir}/packages/#{name}")
968
- end
969
- @packages = list
970
- end
971
-
972
1083
  #
973
1084
  # Task Handlers
974
1085
  #
@@ -992,15 +1103,21 @@ class ToplevelInstallerMulti < ToplevelInstaller
992
1103
  run_hook 'post-install'
993
1104
  end
994
1105
 
1106
+ def exec_test
1107
+ run_hook 'pre-test'
1108
+ each_selected_installers {|inst| inst.exec_test }
1109
+ run_hook 'post-test'
1110
+ end
1111
+
995
1112
  def exec_clean
996
- rm_f ConfigTable.savefile
1113
+ rm_f @config.savefile
997
1114
  run_hook 'pre-clean'
998
1115
  each_selected_installers {|inst| inst.exec_clean }
999
1116
  run_hook 'post-clean'
1000
1117
  end
1001
1118
 
1002
1119
  def exec_distclean
1003
- rm_f ConfigTable.savefile
1120
+ rm_f @config.savefile
1004
1121
  run_hook 'pre-distclean'
1005
1122
  each_selected_installers {|inst| inst.exec_distclean }
1006
1123
  run_hook 'post-distclean'
@@ -1013,7 +1130,7 @@ class ToplevelInstallerMulti < ToplevelInstaller
1013
1130
  def each_selected_installers
1014
1131
  Dir.mkdir 'packages' unless File.dir?('packages')
1015
1132
  @selected.each do |pack|
1016
- $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose']
1133
+ $stderr.puts "Processing the package `#{pack}' ..." if verbose?
1017
1134
  Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
1018
1135
  Dir.chdir "packages/#{pack}"
1019
1136
  yield @installers[pack]
@@ -1021,28 +1138,32 @@ class ToplevelInstallerMulti < ToplevelInstaller
1021
1138
  end
1022
1139
  end
1023
1140
 
1141
+ def run_hook(id)
1142
+ @root_installer.run_hook id
1143
+ end
1144
+
1145
+ # module FileOperations requires this
1024
1146
  def verbose?
1025
- @options['verbose']
1147
+ @config.verbose?
1026
1148
  end
1027
1149
 
1150
+ # module FileOperations requires this
1028
1151
  def no_harm?
1029
- @options['no-harm']
1152
+ @config.no_harm?
1030
1153
  end
1031
1154
 
1032
- end
1155
+ end # class ToplevelInstallerMulti
1033
1156
 
1034
1157
 
1035
1158
  class Installer
1036
1159
 
1037
- FILETYPES = %w( bin lib ext data )
1160
+ FILETYPES = %w( bin lib ext data conf man )
1038
1161
 
1039
- include HookScriptAPI
1040
- include HookUtils
1041
1162
  include FileOperations
1163
+ include HookScriptAPI
1042
1164
 
1043
- def initialize(config, opt, srcroot, objroot)
1165
+ def initialize(config, srcroot, objroot)
1044
1166
  @config = config
1045
- @options = opt
1046
1167
  @srcdir = File.expand_path(srcroot)
1047
1168
  @objdir = File.expand_path(objroot)
1048
1169
  @currdir = '.'
@@ -1052,6 +1173,9 @@ class Installer
1052
1173
  "#<#{self.class} #{File.basename(@srcdir)}>"
1053
1174
  end
1054
1175
 
1176
+ def noop(rel)
1177
+ end
1178
+
1055
1179
  #
1056
1180
  # Hook Script API base methods
1057
1181
  #
@@ -1069,23 +1193,25 @@ class Installer
1069
1193
  end
1070
1194
 
1071
1195
  #
1072
- # configs/options
1196
+ # Config Access
1073
1197
  #
1074
1198
 
1075
- def no_harm?
1076
- @options['no-harm']
1199
+ # module FileOperations requires this
1200
+ def verbose?
1201
+ @config.verbose?
1077
1202
  end
1078
1203
 
1079
- def verbose?
1080
- @options['verbose']
1204
+ # module FileOperations requires this
1205
+ def no_harm?
1206
+ @config.no_harm?
1081
1207
  end
1082
1208
 
1083
1209
  def verbose_off
1084
1210
  begin
1085
- save, @options['verbose'] = @options['verbose'], false
1211
+ save, @config.verbose = @config.verbose?, false
1086
1212
  yield
1087
1213
  ensure
1088
- @options['verbose'] = save
1214
+ @config.verbose = save
1089
1215
  end
1090
1216
  end
1091
1217
 
@@ -1097,22 +1223,19 @@ class Installer
1097
1223
  exec_task_traverse 'config'
1098
1224
  end
1099
1225
 
1100
- def config_dir_bin(rel)
1101
- end
1102
-
1103
- def config_dir_lib(rel)
1104
- end
1226
+ alias config_dir_bin noop
1227
+ alias config_dir_lib noop
1105
1228
 
1106
1229
  def config_dir_ext(rel)
1107
1230
  extconf if extdir?(curr_srcdir())
1108
1231
  end
1109
1232
 
1110
- def extconf
1111
- opt = @options['config-opt'].join(' ')
1112
- command "#{config('rubyprog')} #{curr_srcdir()}/extconf.rb #{opt}"
1113
- end
1233
+ alias config_dir_data noop
1234
+ alias config_dir_conf noop
1235
+ alias config_dir_man noop
1114
1236
 
1115
- def config_dir_data(rel)
1237
+ def extconf
1238
+ ruby "#{curr_srcdir()}/extconf.rb", *@config.config_opt
1116
1239
  end
1117
1240
 
1118
1241
  #
@@ -1124,39 +1247,90 @@ class Installer
1124
1247
  end
1125
1248
 
1126
1249
  def setup_dir_bin(rel)
1127
- all_files_in(curr_srcdir()).each do |fname|
1128
- adjust_shebang "#{curr_srcdir()}/#{fname}"
1250
+ files_of(curr_srcdir()).each do |fname|
1251
+ update_shebang_line "#{curr_srcdir()}/#{fname}"
1129
1252
  end
1130
1253
  end
1131
1254
 
1132
- def adjust_shebang(path)
1255
+ alias setup_dir_lib noop
1256
+
1257
+ def setup_dir_ext(rel)
1258
+ make if extdir?(curr_srcdir())
1259
+ end
1260
+
1261
+ alias setup_dir_data noop
1262
+ alias setup_dir_conf noop
1263
+ alias setup_dir_man noop
1264
+
1265
+ def update_shebang_line(path)
1133
1266
  return if no_harm?
1267
+ return if config('shebang') == 'never'
1268
+ old = Shebang.load(path)
1269
+ if old
1270
+ $stderr.puts "warning: #{path}: Shebang line includes too many args. It is not portable and your program may not work." if old.args.size > 1
1271
+ new = new_shebang(old)
1272
+ return if new.to_s == old.to_s
1273
+ else
1274
+ return unless config('shebang') == 'all'
1275
+ new = Shebang.new(config('rubypath'))
1276
+ end
1277
+ $stderr.puts "updating shebang: #{File.basename(path)}" if verbose?
1278
+ open_atomic_writer(path) {|output|
1279
+ File.open(path, 'rb') {|f|
1280
+ f.gets if old # discard
1281
+ output.puts new.to_s
1282
+ output.print f.read
1283
+ }
1284
+ }
1285
+ end
1286
+
1287
+ def new_shebang(old)
1288
+ if /\Aruby/ =~ File.basename(old.cmd)
1289
+ Shebang.new(config('rubypath'), old.args)
1290
+ elsif File.basename(old.cmd) == 'env' and old.args.first == 'ruby'
1291
+ Shebang.new(config('rubypath'), old.args[1..-1])
1292
+ else
1293
+ return old unless config('shebang') == 'all'
1294
+ Shebang.new(config('rubypath'))
1295
+ end
1296
+ end
1297
+
1298
+ def open_atomic_writer(path, &block)
1134
1299
  tmpfile = File.basename(path) + '.tmp'
1135
1300
  begin
1136
- File.open(path, 'rb') {|r|
1137
- first = r.gets
1138
- return unless File.basename(config('rubypath')) == 'ruby'
1139
- return unless File.basename(first.sub(/\A\#!/, '').split[0]) == 'ruby'
1140
- $stderr.puts "adjusting shebang: #{File.basename(path)}" if verbose?
1141
- File.open(tmpfile, 'wb') {|w|
1142
- w.print first.sub(/\A\#!\s*\S+/, '#! ' + config('rubypath'))
1143
- w.write r.read
1144
- }
1145
- }
1146
- move_file tmpfile, File.basename(path)
1301
+ File.open(tmpfile, 'wb', &block)
1302
+ File.rename tmpfile, File.basename(path)
1147
1303
  ensure
1148
1304
  File.unlink tmpfile if File.exist?(tmpfile)
1149
1305
  end
1150
1306
  end
1151
1307
 
1152
- def setup_dir_lib(rel)
1153
- end
1308
+ class Shebang
1309
+ def Shebang.load(path)
1310
+ line = nil
1311
+ File.open(path) {|f|
1312
+ line = f.gets
1313
+ }
1314
+ return nil unless /\A#!/ =~ line
1315
+ parse(line)
1316
+ end
1154
1317
 
1155
- def setup_dir_ext(rel)
1156
- make if extdir?(curr_srcdir())
1157
- end
1318
+ def Shebang.parse(line)
1319
+ cmd, *args = *line.strip.sub(/\A\#!/, '').split(' ')
1320
+ new(cmd, args)
1321
+ end
1322
+
1323
+ def initialize(cmd, args = [])
1324
+ @cmd = cmd
1325
+ @args = args
1326
+ end
1158
1327
 
1159
- def setup_dir_data(rel)
1328
+ attr_reader :cmd
1329
+ attr_reader :args
1330
+
1331
+ def to_s
1332
+ "#! #{@cmd}" + (@args.empty? ? '' : " #{@args.join(' ')}")
1333
+ end
1160
1334
  end
1161
1335
 
1162
1336
  #
@@ -1169,63 +1343,77 @@ class Installer
1169
1343
  end
1170
1344
 
1171
1345
  def install_dir_bin(rel)
1172
- install_files collect_filenames_auto(), "#{config('bindir')}/#{rel}", 0755
1346
+ install_files targetfiles(), "#{config('bindir')}/#{rel}", 0755
1173
1347
  end
1174
1348
 
1175
1349
  def install_dir_lib(rel)
1176
- install_files ruby_scripts(), "#{config('rbdir')}/#{rel}", 0644
1350
+ install_files libfiles(), "#{config('rbdir')}/#{rel}", 0644
1177
1351
  end
1178
1352
 
1179
1353
  def install_dir_ext(rel)
1180
1354
  return unless extdir?(curr_srcdir())
1181
- install_files ruby_extentions('.'),
1355
+ install_files rubyextentions('.'),
1182
1356
  "#{config('sodir')}/#{File.dirname(rel)}",
1183
1357
  0555
1184
1358
  end
1185
1359
 
1186
1360
  def install_dir_data(rel)
1187
- install_files collect_filenames_auto(), "#{config('datadir')}/#{rel}", 0644
1361
+ install_files targetfiles(), "#{config('datadir')}/#{rel}", 0644
1362
+ end
1363
+
1364
+ def install_dir_conf(rel)
1365
+ # FIXME: should not remove current config files
1366
+ # (rename previous file to .old/.org)
1367
+ install_files targetfiles(), "#{config('sysconfdir')}/#{rel}", 0644
1368
+ end
1369
+
1370
+ def install_dir_man(rel)
1371
+ install_files targetfiles(), "#{config('mandir')}/#{rel}", 0644
1188
1372
  end
1189
1373
 
1190
1374
  def install_files(list, dest, mode)
1191
- mkdir_p dest, @options['install-prefix']
1375
+ mkdir_p dest, @config.install_prefix
1192
1376
  list.each do |fname|
1193
- install fname, dest, mode, @options['install-prefix']
1377
+ install fname, dest, mode, @config.install_prefix
1194
1378
  end
1195
1379
  end
1196
1380
 
1197
- def ruby_scripts
1198
- collect_filenames_auto().select {|n| /\.rb\z/ =~ n }
1381
+ def libfiles
1382
+ glob_reject(%w(*.y *.output), targetfiles())
1199
1383
  end
1200
-
1384
+
1385
+ def rubyextentions(dir)
1386
+ ents = glob_select("*.#{@config.dllext}", targetfiles())
1387
+ if ents.empty?
1388
+ setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
1389
+ end
1390
+ ents
1391
+ end
1392
+
1393
+ def targetfiles
1394
+ mapdir(existfiles() - hookfiles())
1395
+ end
1396
+
1397
+ def mapdir(ents)
1398
+ ents.map {|ent|
1399
+ if File.exist?(ent)
1400
+ then ent # objdir
1401
+ else "#{curr_srcdir()}/#{ent}" # srcdir
1402
+ end
1403
+ }
1404
+ end
1405
+
1201
1406
  # picked up many entries from cvs-1.11.1/src/ignore.c
1202
- reject_patterns = %w(
1407
+ JUNK_FILES = %w(
1203
1408
  core RCSLOG tags TAGS .make.state
1204
1409
  .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
1205
1410
  *~ *.old *.bak *.BAK *.orig *.rej _$* *$
1206
1411
 
1207
1412
  *.org *.in .*
1208
1413
  )
1209
- mapping = {
1210
- '.' => '\.',
1211
- '$' => '\$',
1212
- '#' => '\#',
1213
- '*' => '.*'
1214
- }
1215
- REJECT_PATTERNS = Regexp.new('\A(?:' +
1216
- reject_patterns.map {|pat|
1217
- pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] }
1218
- }.join('|') +
1219
- ')\z')
1220
-
1221
- def collect_filenames_auto
1222
- mapdir((existfiles() - hookfiles()).reject {|fname|
1223
- REJECT_PATTERNS =~ fname
1224
- })
1225
- end
1226
1414
 
1227
1415
  def existfiles
1228
- all_files_in(curr_srcdir()) | all_files_in('.')
1416
+ glob_reject(JUNK_FILES, (files_of(curr_srcdir()) | files_of('.')))
1229
1417
  end
1230
1418
 
1231
1419
  def hookfiles
@@ -1234,24 +1422,49 @@ class Installer
1234
1422
  }.flatten
1235
1423
  end
1236
1424
 
1237
- def mapdir(filelist)
1238
- filelist.map {|fname|
1239
- if File.exist?(fname) # objdir
1240
- fname
1241
- else # srcdir
1242
- File.join(curr_srcdir(), fname)
1243
- end
1244
- }
1425
+ def glob_select(pat, ents)
1426
+ re = globs2re([pat])
1427
+ ents.select {|ent| re =~ ent }
1245
1428
  end
1246
1429
 
1247
- def ruby_extentions(dir)
1248
- Dir.open(dir) {|d|
1249
- ents = d.select {|fname| /\.#{::Config::CONFIG['DLEXT']}\z/ =~ fname }
1250
- if ents.empty?
1251
- setup_rb_error "no ruby extention exists: 'ruby #{$0} setup' first"
1252
- end
1253
- return ents
1254
- }
1430
+ def glob_reject(pats, ents)
1431
+ re = globs2re(pats)
1432
+ ents.reject {|ent| re =~ ent }
1433
+ end
1434
+
1435
+ GLOB2REGEX = {
1436
+ '.' => '\.',
1437
+ '$' => '\$',
1438
+ '#' => '\#',
1439
+ '*' => '.*'
1440
+ }
1441
+
1442
+ def globs2re(pats)
1443
+ /\A(?:#{
1444
+ pats.map {|pat| pat.gsub(/[\.\$\#\*]/) {|ch| GLOB2REGEX[ch] } }.join('|')
1445
+ })\z/
1446
+ end
1447
+
1448
+ #
1449
+ # TASK test
1450
+ #
1451
+
1452
+ TESTDIR = 'test'
1453
+
1454
+ def exec_test
1455
+ unless File.directory?('test')
1456
+ $stderr.puts 'no test in this package' if verbose?
1457
+ return
1458
+ end
1459
+ $stderr.puts 'Running tests...' if verbose?
1460
+ begin
1461
+ require 'test/unit'
1462
+ rescue LoadError
1463
+ setup_rb_error 'test/unit cannot loaded. You need Ruby 1.8 or later to invoke this task.'
1464
+ end
1465
+ runner = Test::Unit::AutoRunner.new(true)
1466
+ runner.to_run << TESTDIR
1467
+ runner.run
1255
1468
  end
1256
1469
 
1257
1470
  #
@@ -1260,53 +1473,51 @@ class Installer
1260
1473
 
1261
1474
  def exec_clean
1262
1475
  exec_task_traverse 'clean'
1263
- rm_f ConfigTable.savefile
1476
+ rm_f @config.savefile
1264
1477
  rm_f 'InstalledFiles'
1265
1478
  end
1266
1479
 
1267
- def clean_dir_bin(rel)
1268
- end
1269
-
1270
- def clean_dir_lib(rel)
1271
- end
1480
+ alias clean_dir_bin noop
1481
+ alias clean_dir_lib noop
1482
+ alias clean_dir_data noop
1483
+ alias clean_dir_conf noop
1484
+ alias clean_dir_man noop
1272
1485
 
1273
1486
  def clean_dir_ext(rel)
1274
1487
  return unless extdir?(curr_srcdir())
1275
1488
  make 'clean' if File.file?('Makefile')
1276
1489
  end
1277
1490
 
1278
- def clean_dir_data(rel)
1279
- end
1280
-
1281
1491
  #
1282
1492
  # TASK distclean
1283
1493
  #
1284
1494
 
1285
1495
  def exec_distclean
1286
1496
  exec_task_traverse 'distclean'
1287
- rm_f ConfigTable.savefile
1497
+ rm_f @config.savefile
1288
1498
  rm_f 'InstalledFiles'
1289
1499
  end
1290
1500
 
1291
- def distclean_dir_bin(rel)
1292
- end
1293
-
1294
- def distclean_dir_lib(rel)
1295
- end
1501
+ alias distclean_dir_bin noop
1502
+ alias distclean_dir_lib noop
1296
1503
 
1297
1504
  def distclean_dir_ext(rel)
1298
1505
  return unless extdir?(curr_srcdir())
1299
1506
  make 'distclean' if File.file?('Makefile')
1300
1507
  end
1301
1508
 
1509
+ alias distclean_dir_data noop
1510
+ alias distclean_dir_conf noop
1511
+ alias distclean_dir_man noop
1512
+
1302
1513
  #
1303
- # lib
1514
+ # Traversing
1304
1515
  #
1305
1516
 
1306
1517
  def exec_task_traverse(task)
1307
1518
  run_hook "pre-#{task}"
1308
1519
  FILETYPES.each do |type|
1309
- if config('without-ext') == 'yes' and type == 'ext'
1520
+ if type == 'ext' and config('without-ext') == 'yes'
1310
1521
  $stderr.puts 'skipping ext/* by user option' if verbose?
1311
1522
  next
1312
1523
  end
@@ -1319,7 +1530,7 @@ class Installer
1319
1530
  dive_into(rel) {
1320
1531
  run_hook "pre-#{task}"
1321
1532
  __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
1322
- all_dirs_in(curr_srcdir()).each do |d|
1533
+ directories_of(curr_srcdir()).each do |d|
1323
1534
  traverse task, "#{rel}/#{d}", mid
1324
1535
  end
1325
1536
  run_hook "post-#{task}"
@@ -1341,16 +1552,30 @@ class Installer
1341
1552
  @currdir = File.dirname(rel)
1342
1553
  end
1343
1554
 
1344
- end
1555
+ def run_hook(id)
1556
+ path = [ "#{curr_srcdir()}/#{id}",
1557
+ "#{curr_srcdir()}/#{id}.rb" ].detect {|cand| File.file?(cand) }
1558
+ return unless path
1559
+ begin
1560
+ instance_eval File.read(path), path, 1
1561
+ rescue
1562
+ raise if $DEBUG
1563
+ setup_rb_error "hook #{path} failed:\n" + $!.message
1564
+ end
1565
+ end
1566
+
1567
+ end # class Installer
1568
+
1569
+
1570
+ class SetupError < StandardError; end
1345
1571
 
1572
+ def setup_rb_error(msg)
1573
+ raise SetupError, msg
1574
+ end
1346
1575
 
1347
1576
  if $0 == __FILE__
1348
1577
  begin
1349
- if multipackage_install?
1350
- ToplevelInstallerMulti.invoke
1351
- else
1352
- ToplevelInstaller.invoke
1353
- end
1578
+ ToplevelInstaller.invoke
1354
1579
  rescue SetupError
1355
1580
  raise if $DEBUG
1356
1581
  $stderr.puts $!.message