ruby-rpm 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,341 @@
1
+ /* -*- mode: C; c-basic-offset: 4; tab-width: 4; -*- */
2
+ /* Ruby/RPM
3
+ *
4
+ * Copyright (C) 2002 Kenta MURATA <muraken2@nifty.com>.
5
+ */
6
+
7
+ /* $Id: version.c 22 2004-03-29 03:42:35Z zaki $ */
8
+
9
+ #include "private.h"
10
+
11
+ VALUE rpm_cVersion;
12
+
13
+ static ID id_v;
14
+ static ID id_r;
15
+ static ID id_e;
16
+
17
+ /* from rpm-4.0.4/lib/depends.c */
18
+ static void
19
+ parseEVR(char* evr, const char** ep, const char** vp, const char** rp)
20
+ {
21
+ const char* epoch;
22
+ const char* version; /* assume only version is present */
23
+ const char* release;
24
+ #if 0
25
+ naze?
26
+ char* evr;
27
+ #endif
28
+ char* s;
29
+ char* se;
30
+
31
+ s = evr;
32
+ while (*s && xisdigit(*s)) s++; /* s points to epoch terminator */
33
+ se = strrchr(s, '-'); /* se points to version terminator */
34
+
35
+ if (*s == ':') {
36
+ epoch = evr;
37
+ *s++ = '\0';
38
+ version = s;
39
+ if (*epoch == '\0') epoch = "0";
40
+ }
41
+ else {
42
+ epoch = NULL; /* disable epoch compare if missing */
43
+ version = evr;
44
+ }
45
+
46
+ if (se) {
47
+ *se++ = '\0';
48
+ release = se;
49
+ }
50
+ else {
51
+ release = NULL;
52
+ }
53
+
54
+ if (ep) *ep = epoch;
55
+ if (vp) *vp = version;
56
+ if (rp) *rp = release;
57
+ }
58
+
59
+ static void
60
+ version_parse(const char* str, VALUE* v, VALUE* r, VALUE* e)
61
+ {
62
+ char* evr;
63
+ const char* epoch;
64
+ const char* version;
65
+ const char* release;
66
+
67
+ *v = *r = *e = Qnil;
68
+
69
+ if (str == NULL) return;
70
+
71
+ evr = ALLOCA_N(char, strlen(str)+1);
72
+ strcpy(evr, str);
73
+
74
+ parseEVR(evr, &epoch, &version, &release);
75
+
76
+ if (epoch && *epoch && atol(epoch) >= 0) {
77
+ if (e) *e = LONG2NUM(atol(epoch));
78
+ }
79
+
80
+ if (v) *v = rb_str_new2(version);
81
+ if (release && *release) {
82
+ if (r) *r = rb_str_new2(release);
83
+ }
84
+ }
85
+
86
+ static VALUE
87
+ version_initialize(int argc, VALUE* argv, VALUE ver)
88
+ {
89
+ VALUE v = Qnil;
90
+ VALUE r = Qnil;
91
+ VALUE e = Qnil;
92
+
93
+ switch (argc) {
94
+ case 0:
95
+ rb_raise(rb_eArgError, "argument too few(1..3)");
96
+
97
+ case 1:
98
+ if (TYPE(argv[0]) != T_STRING) {
99
+ rb_raise(rb_eTypeError, "illegal argument type");
100
+ }
101
+ version_parse(RSTRING(argv[0])->ptr, &v, &r, &e);
102
+ break;
103
+
104
+ case 2:
105
+ if (TYPE(argv[0]) != T_STRING) {
106
+ rb_raise(rb_eTypeError, "illegal argument type");
107
+ }
108
+ version_parse(RSTRING(argv[0])->ptr, &v, &r, &e);
109
+ if (e != Qnil) {
110
+ rb_raise(rb_eTypeError, "illegal argument value");
111
+ }
112
+ e = rb_Integer(argv[1]);
113
+ break;
114
+
115
+ case 3:
116
+ if (TYPE(argv[0]) != T_STRING
117
+ || TYPE(argv[1]) != T_STRING) {
118
+ rb_raise(rb_eTypeError, "illegal argument type");
119
+ }
120
+ v = rb_str_new2(RSTRING(argv[0])->ptr);
121
+ r = rb_str_new2(RSTRING(argv[1])->ptr);
122
+ e = rb_Integer(argv[2]);
123
+ break;
124
+
125
+ default:
126
+ rb_raise(rb_eArgError, "argument too many(1..3)");
127
+ }
128
+
129
+ if (NIL_P(v) || (!NIL_P(e) && NUM2INT(e) < 0)) {
130
+ rb_raise(rb_eArgError, "illegal argument value");
131
+ }
132
+
133
+ rb_ivar_set(ver, id_v, v);
134
+ rb_ivar_set(ver, id_r, r);
135
+ rb_ivar_set(ver, id_e, e);
136
+
137
+ return ver;
138
+ }
139
+
140
+ VALUE
141
+ rpm_version_new(const char* vr)
142
+ {
143
+ VALUE ver;
144
+ VALUE argv[1];
145
+ argv[0] = rb_str_new2(vr);
146
+
147
+ ver = rb_newobj();
148
+ OBJSETUP(ver, rpm_cVersion, T_OBJECT);
149
+ rb_obj_call_init(ver, 1, argv);
150
+
151
+ return ver;
152
+ }
153
+
154
+ VALUE
155
+ rpm_version_new2(const char* vr, int e)
156
+ {
157
+ VALUE ver;
158
+ VALUE argv[2];
159
+
160
+ argv[0] = rb_str_new2(vr);
161
+ argv[1] = INT2NUM(e);
162
+
163
+ ver = rb_newobj();
164
+ OBJSETUP(ver, rpm_cVersion, T_OBJECT);
165
+ rb_obj_call_init(ver, 2, argv);
166
+
167
+ return ver;
168
+ }
169
+
170
+ VALUE
171
+ rpm_version_new3(const char* v, const char* r, int e)
172
+ {
173
+ VALUE ver;
174
+ VALUE argv[3];
175
+
176
+ argv[0] = rb_str_new2(v);
177
+ argv[1] = rb_str_new2(r);
178
+ argv[2] = INT2NUM(e);
179
+
180
+ ver = rb_newobj();
181
+ OBJSETUP(ver, rpm_cVersion, T_OBJECT);
182
+ rb_obj_call_init(ver, 3, argv);
183
+
184
+ return ver;
185
+ }
186
+
187
+ VALUE
188
+ rpm_version_cmp(VALUE ver, VALUE other)
189
+ {
190
+ VALUE ve,oe;
191
+ VALUE vr,or;
192
+ VALUE vv,ov;
193
+ int sense = 0;
194
+
195
+ if (rb_obj_is_kind_of(other, rpm_cVersion) != Qtrue) {
196
+ rb_raise(rb_eTypeError, "illegal argument type");
197
+ }
198
+
199
+ ve = rb_ivar_get(ver,id_e);
200
+ oe = rb_ivar_get(other,id_e);
201
+ if (!NIL_P(ve) && NIL_P(oe))
202
+ return INT2FIX(1);
203
+ else if (NIL_P(ve) && !NIL_P(oe))
204
+ return INT2FIX(-1);
205
+ else if (!NIL_P(ve) && !NIL_P(oe)) {
206
+ if (NUM2INT(ve) < NUM2INT(oe))
207
+ return INT2FIX(-1);
208
+ else if (NUM2INT(ve) > NUM2INT(oe))
209
+ return INT2FIX(1);
210
+ }
211
+
212
+ vv = rb_ivar_get(ver,id_v);
213
+ ov = rb_ivar_get(other,id_v);
214
+ if (!NIL_P(vv) && NIL_P(ov)) /* XXX */
215
+ return INT2FIX(1);
216
+ else if (NIL_P(vv) && !NIL_P(ov)) /* XXX */
217
+ return INT2FIX(-1);
218
+ else if (!NIL_P(vv) && !NIL_P(ov)) {
219
+ sense = rpmvercmp(RSTRING(vv)->ptr, RSTRING(ov)->ptr);
220
+ if (sense)
221
+ return INT2FIX(sense);
222
+ }
223
+
224
+ vr = rb_ivar_get(ver,id_r);
225
+ or = rb_ivar_get(other,id_r);
226
+ if (!NIL_P(vr) && NIL_P(or))
227
+ return INT2FIX(1);
228
+ else if (NIL_P(vr) && !NIL_P(or))
229
+ return INT2FIX(-1);
230
+ else if (!NIL_P(vr) && !NIL_P(or)) {
231
+ sense = rpmvercmp(RSTRING(vr)->ptr, RSTRING(or)->ptr);
232
+ }
233
+ return INT2FIX(sense);
234
+ }
235
+
236
+ VALUE
237
+ rpm_version_is_newer(VALUE ver, VALUE other)
238
+ {
239
+ return (NUM2INT(rpm_version_cmp(ver, other)) > 0) ? Qtrue : Qfalse;
240
+ }
241
+
242
+ VALUE
243
+ rpm_version_is_older(VALUE ver, VALUE other)
244
+ {
245
+ return rpm_version_is_newer(ver, other) ? Qfalse : Qtrue;
246
+ }
247
+
248
+ VALUE
249
+ rpm_version_get_v(VALUE ver)
250
+ {
251
+ return rb_ivar_get(ver, id_v);
252
+ }
253
+
254
+ VALUE
255
+ rpm_version_get_r(VALUE ver)
256
+ {
257
+ return rb_ivar_get(ver, id_r);
258
+ }
259
+
260
+ VALUE
261
+ rpm_version_get_e(VALUE ver)
262
+ {
263
+ return rb_ivar_get(ver, id_e);
264
+ }
265
+
266
+ VALUE
267
+ rpm_version_to_s(VALUE ver)
268
+ {
269
+ char buf[BUFSIZ];
270
+ char *p = buf;
271
+ VALUE v, r;
272
+ v = rb_ivar_get(ver, id_v);
273
+ r = rb_ivar_get(ver, id_r);
274
+ strcpy(p, RSTRING(v)->ptr);
275
+ if (!NIL_P(r)) {
276
+ strcat(p, "-");
277
+ strcat(p, RSTRING(r)->ptr);
278
+ }
279
+ return rb_str_new2(buf);
280
+ }
281
+
282
+ VALUE
283
+ rpm_version_to_vre(VALUE ver)
284
+ {
285
+ char buf[BUFSIZ];
286
+ char *p = buf;
287
+ VALUE v, r, e;
288
+ v = rb_ivar_get(ver, id_v);
289
+ r = rb_ivar_get(ver, id_r);
290
+ e = rb_ivar_get(ver, id_e);
291
+ if (!NIL_P(e)) {
292
+ snprintf(buf,BUFSIZ,"%d:",NUM2INT(e));
293
+ p += strlen(buf);
294
+ }
295
+ strcpy(p, RSTRING(v)->ptr);
296
+ if (!NIL_P(r)) {
297
+ strcat(p, "-");
298
+ strcat(p, RSTRING(r)->ptr);
299
+ }
300
+ return rb_str_new2(buf);
301
+ }
302
+
303
+ VALUE
304
+ rpm_version_inspect(VALUE ver)
305
+ {
306
+ char buf[BUFSIZ];
307
+ char *p = buf;
308
+ VALUE v, r, e;
309
+ v = rb_ivar_get(ver, id_v);
310
+ r = rb_ivar_get(ver, id_r);
311
+ e = rb_ivar_get(ver, id_e);
312
+
313
+ if (!NIL_P(e)) {
314
+ snprintf(buf, BUFSIZ, "#<RPM::Version v=%s, r=%s, e=%d>", RSTRING(rb_inspect(v))->ptr, RSTRING(rb_inspect(r))->ptr, NUM2INT(e));
315
+ } else {
316
+ snprintf(buf, BUFSIZ, "#<RPM::Version v=%s, r=%s>", RSTRING(rb_inspect(v))->ptr, RSTRING(rb_inspect(r))->ptr);
317
+ }
318
+
319
+ return rb_str_new2(buf);
320
+ }
321
+
322
+ void
323
+ Init_rpm_version(void)
324
+ {
325
+ rpm_cVersion = rb_define_class_under(rpm_mRPM, "Version", rb_cObject);
326
+ rb_include_module(rpm_cVersion, rb_mComparable);
327
+ rb_define_method(rpm_cVersion, "initialize", version_initialize, -1);
328
+ rb_define_method(rpm_cVersion, "<=>", rpm_version_cmp, 1);
329
+ rb_define_method(rpm_cVersion, "newer?", rpm_version_is_newer, 1);
330
+ rb_define_method(rpm_cVersion, "older?", rpm_version_is_older, 1);
331
+ rb_define_method(rpm_cVersion, "v", rpm_version_get_v, 0);
332
+ rb_define_method(rpm_cVersion, "r", rpm_version_get_r, 0);
333
+ rb_define_method(rpm_cVersion, "e", rpm_version_get_e, 0);
334
+ rb_define_method(rpm_cVersion, "to_s", rpm_version_to_s, 0);
335
+ rb_define_method(rpm_cVersion, "to_vre", rpm_version_to_vre, 0);
336
+ rb_define_method(rpm_cVersion, "inspect", rpm_version_inspect, 0);
337
+
338
+ id_v = rb_intern("version");
339
+ id_r = rb_intern("release");
340
+ id_e = rb_intern("epoch");
341
+ }
@@ -0,0 +1,1015 @@
1
+ #
2
+ # This file is automatically generated. DO NOT MODIFY!
3
+ #
4
+ # install.rb
5
+ #
6
+ # Copyright (c) 2000-2002 Minero Aoki <aamine@loveruby.net>
7
+ #
8
+ # This program is free software.
9
+ # You can distribute/modify this program under the terms of
10
+ # the GNU Lesser General Public License version 2.
11
+ #
12
+
13
+ ### begin compat.rb
14
+
15
+ unless Enumerable.instance_methods.include? 'inject' then
16
+ module Enumerable
17
+ def inject( result )
18
+ each do |i|
19
+ result = yield(result, i)
20
+ end
21
+ result
22
+ end
23
+ end
24
+ end
25
+
26
+ def File.read_all( fname )
27
+ File.open(fname, 'rb') {|f| return f.read }
28
+ end
29
+
30
+ def File.write( fname, str )
31
+ File.open(fname, 'wb') {|f| f.write str }
32
+ end
33
+
34
+ ### end compat.rb
35
+ ### begin config.rb
36
+
37
+ if i = ARGV.index(/\A--rbconfig=/) then
38
+ file = $'
39
+ ARGV.delete_at(i)
40
+ require file
41
+ else
42
+ require 'rbconfig'
43
+ end
44
+
45
+
46
+ class ConfigTable
47
+
48
+ c = ::Config::CONFIG
49
+
50
+ rubypath = c['bindir'] + '/' + c['ruby_install_name']
51
+
52
+ major = c['MAJOR'].to_i
53
+ minor = c['MINOR'].to_i
54
+ teeny = c['TEENY'].to_i
55
+ version = "#{major}.#{minor}"
56
+
57
+ # ruby ver. >= 1.4.4?
58
+ newpath_p = ((major >= 2) or
59
+ ((major == 1) and
60
+ ((minor >= 5) or
61
+ ((minor == 4) and (teeny >= 4)))))
62
+
63
+ re = Regexp.new('\A' + Regexp.quote(c['prefix']))
64
+ subprefix = lambda {|path|
65
+ re === path and path.sub(re, '$prefix')
66
+ }
67
+
68
+ if c['rubylibdir'] then
69
+ # 1.6.3 < V
70
+ stdruby = subprefix.call(c['rubylibdir'])
71
+ siteruby = subprefix.call(c['sitedir'])
72
+ versite = subprefix.call(c['sitelibdir'])
73
+ sodir = subprefix.call(c['sitearchdir'])
74
+ elsif newpath_p then
75
+ # 1.4.4 <= V <= 1.6.3
76
+ stdruby = "$prefix/lib/ruby/#{version}"
77
+ siteruby = subprefix.call(c['sitedir'])
78
+ versite = siteruby + '/' + version
79
+ sodir = "$site-ruby/#{c['arch']}"
80
+ else
81
+ # V < 1.4.4
82
+ stdruby = "$prefix/lib/ruby/#{version}"
83
+ siteruby = "$prefix/lib/ruby/#{version}/site_ruby"
84
+ versite = siteruby
85
+ sodir = "$site-ruby/#{c['arch']}"
86
+ end
87
+
88
+ DESCRIPTER = [
89
+ [ 'prefix', [ c['prefix'],
90
+ 'path',
91
+ 'path prefix of target environment' ] ],
92
+ [ 'std-ruby', [ stdruby,
93
+ 'path',
94
+ 'the directory for standard ruby libraries' ] ],
95
+ [ 'site-ruby-common', [ siteruby,
96
+ 'path',
97
+ 'the directory for version-independent non-standard ruby libraries' ] ],
98
+ [ 'site-ruby', [ versite,
99
+ 'path',
100
+ 'the directory for non-standard ruby libraries' ] ],
101
+ [ 'bin-dir', [ '$prefix/bin',
102
+ 'path',
103
+ 'the directory for commands' ] ],
104
+ [ 'rb-dir', [ '$site-ruby',
105
+ 'path',
106
+ 'the directory for ruby scripts' ] ],
107
+ [ 'so-dir', [ sodir,
108
+ 'path',
109
+ 'the directory for ruby extentions' ] ],
110
+ [ 'data-dir', [ '$prefix/share',
111
+ 'path',
112
+ 'the directory for shared data' ] ],
113
+ [ 'ruby-path', [ rubypath,
114
+ 'path',
115
+ 'path to set to #! line' ] ],
116
+ [ 'ruby-prog', [ rubypath,
117
+ 'name',
118
+ 'the ruby program using for installation' ] ],
119
+ [ 'make-prog', [ 'make',
120
+ 'name',
121
+ 'the make program to compile ruby extentions' ] ],
122
+ [ 'without-ext', [ 'no',
123
+ 'yes/no',
124
+ 'does not compile/install ruby extentions' ] ]
125
+ ]
126
+
127
+ SAVE_FILE = 'config.save'
128
+
129
+ def ConfigTable.each_name( &block )
130
+ keys().each( &block )
131
+ end
132
+
133
+ def ConfigTable.keys
134
+ DESCRIPTER.collect {|k,*dummy| k }
135
+ end
136
+
137
+ def ConfigTable.each_definition( &block )
138
+ DESCRIPTER.each( &block )
139
+ end
140
+
141
+ def ConfigTable.get_entry( name )
142
+ name, ent = DESCRIPTER.assoc(name)
143
+ ent
144
+ end
145
+
146
+ def ConfigTable.get_entry!( name )
147
+ get_entry(name) or raise ArgumentError, "no such config: #{name}"
148
+ end
149
+
150
+ def ConfigTable.add_entry( name, vals )
151
+ ConfigTable::DESCRIPTER.push [name,vals]
152
+ end
153
+
154
+ def ConfigTable.remove_entry( name )
155
+ get_entry name or raise ArgumentError, "no such config: #{name}"
156
+ DESCRIPTER.delete_if {|n,arr| n == name }
157
+ end
158
+
159
+ def ConfigTable.config_key?( name )
160
+ get_entry(name) ? true : false
161
+ end
162
+
163
+ def ConfigTable.bool_config?( name )
164
+ ent = get_entry(name) or return false
165
+ ent[1] == 'yes/no'
166
+ end
167
+
168
+ def ConfigTable.value_config?( name )
169
+ ent = get_entry(name) or return false
170
+ ent[1] != 'yes/no'
171
+ end
172
+
173
+ def ConfigTable.path_config?( name )
174
+ ent = get_entry(name) or return false
175
+ ent[1] == 'path'
176
+ end
177
+
178
+
179
+ class << self
180
+
181
+ alias newobj new
182
+
183
+ def new
184
+ c = newobj()
185
+ c.__send__ :init
186
+ c
187
+ end
188
+
189
+ def load
190
+ c = newobj()
191
+ File.file? SAVE_FILE or
192
+ raise InstallError, "#{File.basename $0} config first"
193
+ File.foreach( SAVE_FILE ) do |line|
194
+ k, v = line.split( '=', 2 )
195
+ c.instance_eval {
196
+ @table[k] = v.strip
197
+ }
198
+ end
199
+ c
200
+ end
201
+
202
+ end
203
+
204
+ def initialize
205
+ @table = {}
206
+ end
207
+
208
+ def init
209
+ DESCRIPTER.each do |k, (default, vname, desc, default2)|
210
+ @table[k] = default
211
+ end
212
+ end
213
+ private :init
214
+
215
+ def save
216
+ File.open( SAVE_FILE, 'w' ) {|f|
217
+ @table.each do |k, v|
218
+ f.printf "%s=%s\n", k, v if v
219
+ end
220
+ }
221
+ end
222
+
223
+ def []=( k, v )
224
+ ConfigTable.config_key? k or raise InstallError, "unknown config option #{k}"
225
+ if ConfigTable.path_config? k then
226
+ @table[k] = (v[0,1] != '$') ? File.expand_path(v) : v
227
+ else
228
+ @table[k] = v
229
+ end
230
+ end
231
+
232
+ def []( key )
233
+ @table[key] or return nil
234
+ @table[key].gsub( %r<\$([^/]+)> ) { self[$1] }
235
+ end
236
+
237
+ def set_raw( key, val )
238
+ @table[key] = val
239
+ end
240
+
241
+ def get_raw( key )
242
+ @table[key]
243
+ end
244
+
245
+ end
246
+
247
+
248
+ class MetaConfigEnvironment
249
+
250
+ def self.eval_file( file )
251
+ return unless File.file? file
252
+ new.instance_eval File.read_all(file), file, 1
253
+ end
254
+
255
+ private
256
+
257
+ def config_names
258
+ ConfigTable.keys
259
+ end
260
+
261
+ def config?( name )
262
+ ConfigTable.config_key? name
263
+ end
264
+
265
+ def bool_config?( name )
266
+ ConfigTable.bool_config? name
267
+ end
268
+
269
+ def value_config?( name )
270
+ ConfigTable.value_config? name
271
+ end
272
+
273
+ def path_config?( name )
274
+ ConfigTable.path_config? name
275
+ end
276
+
277
+ def add_config( name, argname, default, desc )
278
+ ConfigTable.add_entry name,[default,argname,desc]
279
+ end
280
+
281
+ def add_path_config( name, default, desc )
282
+ add_config name, 'path', default, desc
283
+ end
284
+
285
+ def add_bool_config( name, default, desc )
286
+ add_config name, 'yes/no', default ? 'yes' : 'no', desc
287
+ end
288
+
289
+ def set_config_default( name, default )
290
+ if bool_config? name then
291
+ ConfigTable.get_entry!(name)[0] = default ? 'yes' : 'no'
292
+ else
293
+ ConfigTable.get_entry!(name)[0] = default
294
+ end
295
+ end
296
+
297
+ def remove_config( name )
298
+ ent = ConfigTable.get_entry(name)
299
+ ConfigTable.remove_entry name
300
+ ent
301
+ end
302
+
303
+ end
304
+
305
+ ### end config.rb
306
+ ### begin fileop.rb
307
+
308
+ module FileOperations
309
+
310
+ def mkdir_p( dname, prefix = nil )
311
+ dname = prefix + dname if prefix
312
+ $stderr.puts "mkdir -p #{dname}" if verbose?
313
+ return if no_harm?
314
+
315
+ # does not check '/'... it's too abnormal case
316
+ dirs = dname.split(%r_(?=/)_)
317
+ if /\A[a-z]:\z/i === dirs[0] then
318
+ disk = dirs.shift
319
+ dirs[0] = disk + dirs[0]
320
+ end
321
+ dirs.each_index do |idx|
322
+ path = dirs[0..idx].join('')
323
+ Dir.mkdir path unless dir? path
324
+ end
325
+ end
326
+
327
+ def rm_f( fname )
328
+ $stderr.puts "rm -f #{fname}" if verbose?
329
+ return if no_harm?
330
+
331
+ if File.exist? fname or File.symlink? fname then
332
+ File.chmod 0777, fname
333
+ File.unlink fname
334
+ end
335
+ end
336
+
337
+ def rm_rf( dn )
338
+ $stderr.puts "rm -rf #{dn}" if verbose?
339
+ return if no_harm?
340
+
341
+ Dir.chdir dn
342
+ Dir.foreach('.') do |fn|
343
+ next if fn == '.'
344
+ next if fn == '..'
345
+ if dir? fn then
346
+ verbose_off {
347
+ rm_rf fn
348
+ }
349
+ else
350
+ verbose_off {
351
+ rm_f fn
352
+ }
353
+ end
354
+ end
355
+ Dir.chdir '..'
356
+ Dir.rmdir dn
357
+ end
358
+
359
+ def mv( src, dest )
360
+ rm_f dest
361
+ begin
362
+ File.link src, dest
363
+ rescue
364
+ File.write dest, File.read_all(src)
365
+ File.chmod File.stat(src).mode, dest
366
+ end
367
+ rm_f src
368
+ end
369
+
370
+ def install( from, dest, mode, prefix = nil )
371
+ $stderr.puts "install #{from} #{dest}" if verbose?
372
+ return if no_harm?
373
+
374
+ realdest = prefix + dest if prefix
375
+ if dir? realdest then
376
+ realdest += '/' + File.basename(from)
377
+ end
378
+ str = File.read_all(from)
379
+ if diff? str, realdest then
380
+ verbose_off {
381
+ rm_f realdest if File.exist? realdest
382
+ }
383
+ File.write realdest, str
384
+ File.chmod mode, realdest
385
+
386
+ File.open( objdir + '/InstalledFiles', 'a' ) {|f| f.puts dest }
387
+ end
388
+ end
389
+
390
+ def diff?( orig, targ )
391
+ return true unless File.exist? targ
392
+ orig != File.read_all(targ)
393
+ end
394
+
395
+ def command( str )
396
+ $stderr.puts str if verbose?
397
+ system str or raise RuntimeError, "'system #{str}' failed"
398
+ end
399
+
400
+ def ruby( str )
401
+ command config('ruby-prog') + ' ' + str
402
+ end
403
+
404
+ def dir?( dname )
405
+ # for corrupted windows stat()
406
+ File.directory?( (dname[-1,1] == '/') ? dname : dname + '/' )
407
+ end
408
+
409
+ def all_files( dname )
410
+ Dir.open( dname ) {|d|
411
+ return d.find_all {|n| File.file? "#{dname}/#{n}" }
412
+ }
413
+ end
414
+
415
+ def all_dirs( dname )
416
+ Dir.open( dname ) {|d|
417
+ return d.find_all {|n| dir? "#{dname}/#{n}" } - %w(. ..)
418
+ }
419
+ end
420
+
421
+ end
422
+
423
+ ### end fileop.rb
424
+ ### begin base.rb
425
+
426
+ class InstallError < StandardError; end
427
+
428
+
429
+ class Installer
430
+
431
+ Version = '3.1.1'
432
+ Copyright = 'Copyright (c) 2000-2002 Minero Aoki'
433
+
434
+
435
+ @toplevel = nil
436
+
437
+ def self.declear_toplevel_installer( inst )
438
+ @toplevel and
439
+ raise ArgumentError, 'more than one toplevel installer decleared'
440
+ @toplevel = inst
441
+ end
442
+
443
+ def self.toplevel_installer
444
+ @toplevel
445
+ end
446
+
447
+
448
+ FILETYPES = %w( bin lib ext data )
449
+
450
+ include FileOperations
451
+
452
+ def initialize( config, opt, srcroot, objroot )
453
+ @config = config
454
+ @options = opt
455
+ @srcdir = File.expand_path(srcroot)
456
+ @objdir = File.expand_path(objroot)
457
+ @currdir = '.'
458
+ end
459
+
460
+ def inspect
461
+ "#<#{type} #{__id__}>"
462
+ end
463
+
464
+ #
465
+ # configs/options
466
+ #
467
+
468
+ def get_config( key )
469
+ @config[key]
470
+ end
471
+
472
+ alias config get_config
473
+
474
+ def set_config( key, val )
475
+ @config[key] = val
476
+ end
477
+
478
+ def no_harm?
479
+ @options['no-harm']
480
+ end
481
+
482
+ def verbose?
483
+ @options['verbose']
484
+ end
485
+
486
+ def verbose_off
487
+ save, @options['verbose'] = @options['verbose'], false
488
+ yield
489
+ @options['verbose'] = save
490
+ end
491
+
492
+ #
493
+ # srcdir/objdir
494
+ #
495
+
496
+ attr_reader :srcdir
497
+ alias srcdir_root srcdir
498
+ alias package_root srcdir
499
+
500
+ def curr_srcdir
501
+ "#{@srcdir}/#{@currdir}"
502
+ end
503
+
504
+ attr_reader :objdir
505
+ alias objdir_root objdir
506
+
507
+ def curr_objdir
508
+ "#{@objdir}/#{@currdir}"
509
+ end
510
+
511
+ def srcfile( path )
512
+ curr_srcdir + '/' + path
513
+ end
514
+
515
+ def srcexist?( path )
516
+ File.exist? srcfile(path)
517
+ end
518
+
519
+ def srcdirectory?( path )
520
+ dir? srcfile(path)
521
+ end
522
+
523
+ def srcfile?( path )
524
+ File.file? srcfile(path)
525
+ end
526
+
527
+ def srcentries( path = '.' )
528
+ Dir.open( curr_srcdir + '/' + path ) {|d|
529
+ return d.to_a - %w(. ..) - hookfilenames
530
+ }
531
+ end
532
+
533
+ def srcfiles( path = '.' )
534
+ srcentries(path).find_all {|fname|
535
+ File.file? File.join(curr_srcdir, path, fname)
536
+ }
537
+ end
538
+
539
+ def srcdirectories( path = '.' )
540
+ srcentries(path).find_all {|fname|
541
+ dir? File.join(curr_srcdir, path, fname)
542
+ }
543
+ end
544
+
545
+ def dive_into( rel )
546
+ return unless dir? "#{@srcdir}/#{rel}"
547
+
548
+ dir = File.basename(rel)
549
+ Dir.mkdir dir unless dir? dir
550
+ save = Dir.pwd
551
+ Dir.chdir dir
552
+ $stderr.puts '---> ' + rel if verbose?
553
+ @currdir = rel
554
+ yield
555
+ Dir.chdir save
556
+ $stderr.puts '<--- ' + rel if verbose?
557
+ @currdir = File.dirname(rel)
558
+ end
559
+
560
+ #
561
+ # config
562
+ #
563
+
564
+ def exec_config
565
+ exec_task_traverse 'config'
566
+ end
567
+
568
+ def config_dir_bin( rel )
569
+ end
570
+
571
+ def config_dir_lib( rel )
572
+ end
573
+
574
+ def config_dir_ext( rel )
575
+ extconf if extdir? curr_srcdir
576
+ end
577
+
578
+ def extconf
579
+ opt = @options['config-opt'].join(' ')
580
+ command "#{config('ruby-prog')} #{curr_srcdir}/extconf.rb #{opt}"
581
+ end
582
+
583
+ def config_dir_data( rel )
584
+ end
585
+
586
+ #
587
+ # setup
588
+ #
589
+
590
+ def exec_setup
591
+ exec_task_traverse 'setup'
592
+ end
593
+
594
+ def setup_dir_bin( relpath )
595
+ all_files( curr_srcdir ).each do |fname|
596
+ add_rubypath "#{curr_srcdir}/#{fname}"
597
+ end
598
+ end
599
+
600
+ SHEBANG_RE = /\A\#!\s*\S*ruby\S*/
601
+
602
+ def add_rubypath( path )
603
+ $stderr.puts %Q<set #! line to "\#!#{config('ruby-path')}" for #{path} ...> if verbose?
604
+ return if no_harm?
605
+
606
+ tmpfile = File.basename(path) + '.tmp'
607
+ begin
608
+ File.open( path ) {|r|
609
+ File.open( tmpfile, 'w' ) {|w|
610
+ first = r.gets
611
+ return unless SHEBANG_RE === first # reject '/usr/bin/env ruby'
612
+
613
+ w.print first.sub( SHEBANG_RE, '#!' + config('ruby-path') )
614
+ w.write r.read
615
+ } }
616
+ mv tmpfile, File.basename(path)
617
+ ensure
618
+ rm_f tmpfile if File.exist? tmpfile
619
+ end
620
+ end
621
+
622
+ def setup_dir_lib( relpath )
623
+ end
624
+
625
+ def setup_dir_ext( relpath )
626
+ if extdir? curr_srcdir then
627
+ make
628
+ end
629
+ end
630
+
631
+ def make
632
+ command config('make-prog')
633
+ end
634
+
635
+ def setup_dir_data( relpath )
636
+ end
637
+
638
+ #
639
+ # install
640
+ #
641
+
642
+ def exec_install
643
+ exec_task_traverse 'install'
644
+ end
645
+
646
+ def install_dir_bin( rel )
647
+ install_files targfiles, config('bin-dir') + '/' + rel, 0755
648
+ end
649
+
650
+ def install_dir_lib( rel )
651
+ install_files targfiles, config('rb-dir') + '/' + rel, 0644
652
+ end
653
+
654
+ def install_dir_ext( rel )
655
+ if extdir? curr_srcdir then
656
+ install_dir_ext_main File.dirname(rel)
657
+ end
658
+ end
659
+
660
+ def install_dir_ext_main( rel )
661
+ install_files allext('.'), config('so-dir') + '/' + rel, 0555
662
+ end
663
+
664
+ def install_dir_data( rel )
665
+ install_files targfiles, config('data-dir') + '/' + rel, 0644
666
+ end
667
+
668
+ def install_files( list, dest, mode )
669
+ mkdir_p dest, @options['install-prefix']
670
+ list.each do |fname|
671
+ install fname, dest, mode, @options['install-prefix']
672
+ end
673
+ end
674
+
675
+ def targfiles
676
+ (targfilenames() - hookfilenames()).collect {|fname|
677
+ File.exist?(fname) ? fname : File.join(curr_srcdir(), fname)
678
+ }
679
+ end
680
+
681
+ def targfilenames
682
+ [ curr_srcdir(), '.' ].inject([]) {|ret, dir|
683
+ ret | all_files(dir)
684
+ }
685
+ end
686
+
687
+ def hookfilenames
688
+ %w( pre-%s post-%s pre-%s.rb post-%s.rb ).collect {|fmt|
689
+ %w( config setup install clean ).collect {|t| sprintf fmt, t }
690
+ }.flatten
691
+ end
692
+
693
+ def allext( dir )
694
+ _allext(dir) or raise InstallError,
695
+ "no extention exists: Have you done 'ruby #{$0} setup' ?"
696
+ end
697
+
698
+ DLEXT = /\.#{ ::Config::CONFIG['DLEXT'] }\z/
699
+
700
+ def _allext( dir )
701
+ Dir.open( dir ) {|d|
702
+ return d.find_all {|fname| DLEXT === fname }
703
+ }
704
+ end
705
+
706
+ #
707
+ # clean
708
+ #
709
+
710
+ def exec_clean
711
+ exec_task_traverse 'clean'
712
+ rm_f 'config.save'
713
+ rm_f 'InstalledFiles'
714
+ end
715
+
716
+ def clean_dir_bin( rel )
717
+ end
718
+
719
+ def clean_dir_lib( rel )
720
+ end
721
+
722
+ def clean_dir_ext( rel )
723
+ clean
724
+ end
725
+
726
+ def clean
727
+ command config('make-prog') + ' clean' if File.file? 'Makefile'
728
+ end
729
+
730
+ def clean_dir_data( rel )
731
+ end
732
+
733
+ #
734
+ # lib
735
+ #
736
+
737
+ def exec_task_traverse( task )
738
+ run_hook 'pre-' + task
739
+ FILETYPES.each do |type|
740
+ if config('without-ext') == 'yes' and type == 'ext' then
741
+ $stderr.puts 'skipping ext/* by user option' if verbose?
742
+ next
743
+ end
744
+ traverse task, type, task + '_dir_' + type
745
+ end
746
+ run_hook 'post-' + task
747
+ end
748
+
749
+ def traverse( task, rel, mid )
750
+ dive_into( rel ) {
751
+ run_hook 'pre-' + task
752
+ __send__ mid, rel.sub( %r_\A.*?(?:/|\z)_, '' )
753
+ all_dirs( curr_srcdir ).each do |d|
754
+ traverse task, rel + '/' + d, mid
755
+ end
756
+ run_hook 'post-' + task
757
+ }
758
+ end
759
+
760
+ def run_hook( name )
761
+ try_run_hook curr_srcdir + '/' + name or
762
+ try_run_hook curr_srcdir + '/' + name + '.rb'
763
+ end
764
+
765
+ def try_run_hook( fname )
766
+ return false unless File.file? fname
767
+
768
+ env = self.dup
769
+ begin
770
+ env.instance_eval File.read_all(fname), fname, 1
771
+ rescue
772
+ raise InstallError, "hook #{fname} failed:\n" + $!.message
773
+ end
774
+ true
775
+ end
776
+
777
+ def extdir?( dir )
778
+ File.exist? dir + '/MANIFEST'
779
+ end
780
+
781
+ end
782
+
783
+ ### end base.rb
784
+ ### begin toplevel.rb
785
+
786
+ class ToplevelInstaller < Installer
787
+
788
+ TASKS = [
789
+ [ 'config', 'saves your configurations' ],
790
+ [ 'show', 'shows current configuration' ],
791
+ [ 'setup', 'compiles extention or else' ],
792
+ [ 'install', 'installs files' ],
793
+ [ 'clean', "does `make clean' for each extention" ]
794
+ ]
795
+
796
+
797
+ def initialize( root )
798
+ super nil, {'verbose' => true}, root, '.'
799
+ Installer.declear_toplevel_installer self
800
+ end
801
+
802
+
803
+ def execute
804
+ run_metaconfigs
805
+
806
+ case task = parsearg_global()
807
+ when 'config'
808
+ @config = ConfigTable.new
809
+ else
810
+ @config = ConfigTable.load
811
+ end
812
+ parsearg_TASK task
813
+
814
+ exectask task
815
+ end
816
+
817
+
818
+ def run_metaconfigs
819
+ MetaConfigEnvironment.eval_file "#{srcdir_root}/#{metaconfig}"
820
+ end
821
+
822
+ def metaconfig
823
+ 'metaconfig'
824
+ end
825
+
826
+
827
+ def exectask( task )
828
+ if task == 'show' then
829
+ exec_show
830
+ else
831
+ try task
832
+ end
833
+ end
834
+
835
+ def try( task )
836
+ $stderr.printf "#{File.basename $0}: entering %s phase...\n", task if verbose?
837
+ begin
838
+ __send__ 'exec_' + task
839
+ rescue
840
+ $stderr.printf "%s failed\n", task
841
+ raise
842
+ end
843
+ $stderr.printf "#{File.basename $0}: %s done.\n", task if verbose?
844
+ end
845
+
846
+ #
847
+ # processing arguments
848
+ #
849
+
850
+ def parsearg_global
851
+ task_re = /\A(?:#{TASKS.collect {|i| i[0] }.join '|'})\z/
852
+
853
+ while arg = ARGV.shift do
854
+ case arg
855
+ when /\A\w+\z/
856
+ task_re === arg or raise InstallError, "wrong task: #{arg}"
857
+ return arg
858
+
859
+ when '-q', '--quiet'
860
+ @options['verbose'] = false
861
+
862
+ when '--verbose'
863
+ @options['verbose'] = true
864
+
865
+ when '-h', '--help'
866
+ print_usage $stdout
867
+ exit 0
868
+
869
+ when '-v', '--version'
870
+ puts "#{File.basename $0} version #{Version}"
871
+ exit 0
872
+
873
+ when '--copyright'
874
+ puts Copyright
875
+ exit 0
876
+
877
+ else
878
+ raise InstallError, "unknown global option '#{arg}'"
879
+ end
880
+ end
881
+
882
+ raise InstallError, 'no task or global option given'
883
+ end
884
+
885
+
886
+ def parsearg_TASK( task )
887
+ mid = "parsearg_#{task}"
888
+ if respond_to? mid, true then
889
+ __send__ mid
890
+ else
891
+ ARGV.empty? or
892
+ raise InstallError, "#{task}: unknown options: #{ARGV.join ' '}"
893
+ end
894
+ end
895
+
896
+ def parsearg_config
897
+ re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?/
898
+ @options['config-opt'] = []
899
+
900
+ while i = ARGV.shift do
901
+ if /\A--?\z/ === i then
902
+ @options['config-opt'] = ARGV.dup
903
+ break
904
+ end
905
+ m = re.match(i) or raise InstallError, "config: unknown option #{i}"
906
+ name, value = m.to_a[1,2]
907
+ if value then
908
+ if ConfigTable.bool_config?(name) then
909
+ /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i === value or raise InstallError, "config: --#{name} allows only yes/no for argument"
910
+ value = (/\Ay(es)?|\At(rue)/i === value) ? 'yes' : 'no'
911
+ end
912
+ else
913
+ ConfigTable.bool_config?(name) or raise InstallError, "config: --#{name} requires argument"
914
+ value = 'yes'
915
+ end
916
+ @config[name] = value
917
+ end
918
+ end
919
+
920
+ def parsearg_install
921
+ @options['no-harm'] = false
922
+ @options['install-prefix'] = ''
923
+ while a = ARGV.shift do
924
+ case a
925
+ when /\A--no-harm\z/
926
+ @options['no-harm'] = true
927
+ when /\A--prefix=(.*)\z/
928
+ path = $1
929
+ path = File.expand_path(path) unless path[0,1] == '/'
930
+ @options['install-prefix'] = path
931
+ else
932
+ raise InstallError, "install: unknown option #{a}"
933
+ end
934
+ end
935
+ end
936
+
937
+
938
+ def print_usage( out )
939
+ out.puts
940
+ out.puts 'Usage:'
941
+ out.puts " ruby #{File.basename $0} <global option>"
942
+ out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
943
+
944
+ fmt = " %-20s %s\n"
945
+ out.puts
946
+ out.puts 'Global options:'
947
+ out.printf fmt, '-q,--quiet', 'suppress message outputs'
948
+ out.printf fmt, ' --verbose', 'output messages verbosely'
949
+ out.printf fmt, '-h,--help', 'print this message'
950
+ out.printf fmt, '-v,--version', 'print version and quit'
951
+ out.printf fmt, '--copyright', 'print copyright and quit'
952
+
953
+ out.puts
954
+ out.puts 'Tasks:'
955
+ TASKS.each do |name, desc|
956
+ out.printf " %-10s %s\n", name, desc
957
+ end
958
+
959
+ out.puts
960
+ out.puts 'Options for config:'
961
+ ConfigTable.each_definition do |name, (default, arg, desc, default2)|
962
+ out.printf " %-20s %s [%s]\n",
963
+ '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg),
964
+ desc,
965
+ default2 || default
966
+ end
967
+ out.printf " %-20s %s [%s]\n",
968
+ '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"
969
+
970
+ out.puts
971
+ out.puts 'Options for install:'
972
+ out.printf " %-20s %s [%s]\n",
973
+ '--no-harm', 'only display what to do if given', 'off'
974
+
975
+ out.puts
976
+ end
977
+
978
+ #
979
+ # config
980
+ #
981
+
982
+ def exec_config
983
+ super
984
+ @config.save
985
+ end
986
+
987
+ #
988
+ # show
989
+ #
990
+
991
+ def exec_show
992
+ ConfigTable.each_name do |k|
993
+ v = @config.get_raw(k)
994
+ if not v or v.empty? then
995
+ v = '(not specified)'
996
+ end
997
+ printf "%-10s %s\n", k, v
998
+ end
999
+ end
1000
+
1001
+ end
1002
+
1003
+ ### end toplevel.rb
1004
+
1005
+ if $0 == __FILE__ then
1006
+ begin
1007
+ installer = ToplevelInstaller.new( File.dirname($0) )
1008
+ installer.execute
1009
+ rescue
1010
+ raise if $DEBUG
1011
+ $stderr.puts $!.message
1012
+ $stderr.puts "try 'ruby #{$0} --help' for usage"
1013
+ exit 1
1014
+ end
1015
+ end