sqlite3 1.3.13-x64-mingw32 → 1.5.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sqlite3 might be problematic. Click here for more details.

Files changed (54) hide show
  1. checksums.yaml +5 -5
  2. data/.gemtest +0 -0
  3. data/{API_CHANGES.rdoc → API_CHANGES.md} +3 -4
  4. data/CHANGELOG.md +425 -0
  5. data/CONTRIBUTING.md +24 -0
  6. data/Gemfile +2 -14
  7. data/LICENSE-DEPENDENCIES +20 -0
  8. data/README.md +233 -0
  9. data/ext/sqlite3/aggregator.c +274 -0
  10. data/ext/sqlite3/aggregator.h +12 -0
  11. data/ext/sqlite3/database.c +171 -206
  12. data/ext/sqlite3/database.h +2 -0
  13. data/ext/sqlite3/exception.c +6 -2
  14. data/ext/sqlite3/extconf.rb +236 -55
  15. data/ext/sqlite3/sqlite3.c +12 -1
  16. data/ext/sqlite3/sqlite3_ruby.h +3 -7
  17. data/ext/sqlite3/statement.c +15 -20
  18. data/faq/faq.md +431 -0
  19. data/faq/faq.yml +1 -1
  20. data/lib/sqlite3/2.6/sqlite3_native.so +0 -0
  21. data/lib/sqlite3/2.7/sqlite3_native.so +0 -0
  22. data/lib/sqlite3/3.0/sqlite3_native.so +0 -0
  23. data/lib/sqlite3/constants.rb +2 -1
  24. data/lib/sqlite3/database.rb +202 -52
  25. data/lib/sqlite3/errors.rb +1 -10
  26. data/lib/sqlite3/pragmas.rb +17 -10
  27. data/lib/sqlite3/resultset.rb +2 -10
  28. data/lib/sqlite3/statement.rb +2 -1
  29. data/lib/sqlite3/translator.rb +1 -1
  30. data/lib/sqlite3/version.rb +3 -5
  31. data/test/helper.rb +9 -0
  32. data/test/test_database.rb +126 -11
  33. data/test/test_database_flags.rb +95 -0
  34. data/test/test_database_readwrite.rb +41 -0
  35. data/test/test_integration.rb +12 -81
  36. data/test/test_integration_aggregate.rb +336 -0
  37. data/test/test_integration_resultset.rb +0 -17
  38. data/test/test_sqlite3.rb +9 -0
  39. data/test/test_statement.rb +11 -8
  40. metadata +54 -85
  41. data/CHANGELOG.rdoc +0 -292
  42. data/Manifest.txt +0 -52
  43. data/README.rdoc +0 -118
  44. data/Rakefile +0 -10
  45. data/lib/sqlite3/2.0/sqlite3_native.so +0 -0
  46. data/lib/sqlite3/2.1/sqlite3_native.so +0 -0
  47. data/lib/sqlite3/2.2/sqlite3_native.so +0 -0
  48. data/lib/sqlite3/2.3/sqlite3_native.so +0 -0
  49. data/lib/sqlite3/2.4/sqlite3_native.so +0 -0
  50. data/setup.rb +0 -1333
  51. data/tasks/faq.rake +0 -9
  52. data/tasks/gem.rake +0 -38
  53. data/tasks/native.rake +0 -52
  54. data/tasks/vendor_sqlite3.rake +0 -97
data/setup.rb DELETED
@@ -1,1333 +0,0 @@
1
- #
2
- # setup.rb
3
- #
4
- # Copyright (c) 2000-2004 Minero Aoki
5
- #
6
- # This program is free software.
7
- # You can distribute/modify this program under the terms of
8
- # the GNU LGPL, Lesser General Public License version 2.1.
9
- #
10
-
11
- #
12
- # For backward compatibility
13
- #
14
-
15
- unless Enumerable.method_defined?(:map)
16
- module Enumerable
17
- alias map collect
18
- end
19
- end
20
-
21
- unless Enumerable.method_defined?(:detect)
22
- module Enumerable
23
- alias detect find
24
- end
25
- end
26
-
27
- unless Enumerable.method_defined?(:select)
28
- module Enumerable
29
- alias select find_all
30
- end
31
- end
32
-
33
- unless Enumerable.method_defined?(:reject)
34
- module Enumerable
35
- def reject
36
- select {|i| not yield(i) }
37
- end
38
- end
39
- end
40
-
41
- unless Enumerable.method_defined?(:inject)
42
- module Enumerable
43
- def inject(result)
44
- each do |i|
45
- result = yield(result, i)
46
- end
47
- result
48
- end
49
- end
50
- end
51
-
52
- unless Enumerable.method_defined?(:any?)
53
- module Enumerable
54
- def any?
55
- each do |i|
56
- return true if yield(i)
57
- end
58
- false
59
- end
60
- end
61
- end
62
-
63
- unless File.respond_to?(:read)
64
- def File.read(fname)
65
- open(fname) {|f|
66
- return f.read
67
- }
68
- end
69
- end
70
-
71
- #
72
- # Application independent utilities
73
- #
74
-
75
- def File.binread(fname)
76
- open(fname, 'rb') {|f|
77
- return f.read
78
- }
79
- end
80
-
81
- # for corrupted windows stat(2)
82
- def File.dir?(path)
83
- File.directory?((path[-1,1] == '/') ? path : path + '/')
84
- end
85
-
86
- #
87
- # Config
88
- #
89
-
90
- if arg = ARGV.detect {|arg| /\A--rbconfig=/ =~ arg }
91
- ARGV.delete(arg)
92
- require arg.split(/=/, 2)[1]
93
- $".push 'rbconfig.rb'
94
- else
95
- require 'rbconfig'
96
- end
97
-
98
- def multipackage_install?
99
- FileTest.directory?(File.dirname($0) + '/packages')
100
- end
101
-
102
-
103
- class ConfigTable
104
-
105
- c = ::RbConfig::CONFIG
106
-
107
- rubypath = c['bindir'] + '/' + c['ruby_install_name']
108
-
109
- major = c['MAJOR'].to_i
110
- minor = c['MINOR'].to_i
111
- teeny = c['TEENY'].to_i
112
- version = "#{major}.#{minor}"
113
-
114
- # ruby ver. >= 1.4.4?
115
- newpath_p = ((major >= 2) or
116
- ((major == 1) and
117
- ((minor >= 5) or
118
- ((minor == 4) and (teeny >= 4)))))
119
-
120
- subprefix = lambda {|path|
121
- path.sub(/\A#{Regexp.quote(c['prefix'])}/o, '$prefix')
122
- }
123
-
124
- if c['rubylibdir']
125
- # V < 1.6.3
126
- stdruby = subprefix.call(c['rubylibdir'])
127
- siteruby = subprefix.call(c['sitedir'])
128
- versite = subprefix.call(c['sitelibdir'])
129
- sodir = subprefix.call(c['sitearchdir'])
130
- elsif newpath_p
131
- # 1.4.4 <= V <= 1.6.3
132
- stdruby = "$prefix/lib/ruby/#{version}"
133
- siteruby = subprefix.call(c['sitedir'])
134
- versite = siteruby + '/' + version
135
- sodir = "$site-ruby/#{c['arch']}"
136
- else
137
- # V < 1.4.4
138
- stdruby = "$prefix/lib/ruby/#{version}"
139
- siteruby = "$prefix/lib/ruby/#{version}/site_ruby"
140
- versite = siteruby
141
- sodir = "$site-ruby/#{c['arch']}"
142
- end
143
-
144
- if arg = c['configure_args'].split.detect {|arg| /--with-make-prog=/ =~ arg }
145
- makeprog = arg.sub(/'/, '').split(/=/, 2)[1]
146
- else
147
- makeprog = 'make'
148
- end
149
-
150
- common_descripters = [
151
- [ 'prefix', [ c['prefix'],
152
- 'path',
153
- 'path prefix of target environment' ] ],
154
- [ 'std-ruby', [ stdruby,
155
- 'path',
156
- 'the directory for standard ruby libraries' ] ],
157
- [ 'site-ruby-common', [ siteruby,
158
- 'path',
159
- 'the directory for version-independent non-standard ruby libraries' ] ],
160
- [ 'site-ruby', [ versite,
161
- 'path',
162
- 'the directory for non-standard ruby libraries' ] ],
163
- [ 'bin-dir', [ '$prefix/bin',
164
- 'path',
165
- 'the directory for commands' ] ],
166
- [ 'rb-dir', [ '$site-ruby',
167
- 'path',
168
- 'the directory for ruby scripts' ] ],
169
- [ 'so-dir', [ sodir,
170
- 'path',
171
- 'the directory for ruby extentions' ] ],
172
- [ 'data-dir', [ '$prefix/share',
173
- 'path',
174
- 'the directory for shared data' ] ],
175
- [ 'ruby-path', [ rubypath,
176
- 'path',
177
- 'path to set to #! line' ] ],
178
- [ 'ruby-prog', [ rubypath,
179
- 'name',
180
- 'the ruby program using for installation' ] ],
181
- [ 'make-prog', [ makeprog,
182
- 'name',
183
- 'the make program to compile ruby extentions' ] ],
184
- [ 'without-ext', [ 'no',
185
- 'yes/no',
186
- 'does not compile/install ruby extentions' ] ]
187
- ]
188
- multipackage_descripters = [
189
- [ 'with', [ '',
190
- 'name,name...',
191
- 'package names that you want to install',
192
- 'ALL' ] ],
193
- [ 'without', [ '',
194
- 'name,name...',
195
- 'package names that you do not want to install',
196
- 'NONE' ] ]
197
- ]
198
- if multipackage_install?
199
- DESCRIPTER = common_descripters + multipackage_descripters
200
- else
201
- DESCRIPTER = common_descripters
202
- end
203
-
204
- SAVE_FILE = '.config'
205
-
206
- def ConfigTable.each_name(&block)
207
- keys().each(&block)
208
- end
209
-
210
- def ConfigTable.keys
211
- DESCRIPTER.map {|name, *dummy| name }
212
- end
213
-
214
- def ConfigTable.each_definition(&block)
215
- DESCRIPTER.each(&block)
216
- end
217
-
218
- def ConfigTable.get_entry(name)
219
- name, ent = DESCRIPTER.assoc(name)
220
- ent
221
- end
222
-
223
- def ConfigTable.get_entry!(name)
224
- get_entry(name) or raise ArgumentError, "no such config: #{name}"
225
- end
226
-
227
- def ConfigTable.add_entry(name, vals)
228
- ConfigTable::DESCRIPTER.push [name,vals]
229
- end
230
-
231
- def ConfigTable.remove_entry(name)
232
- get_entry(name) or raise ArgumentError, "no such config: #{name}"
233
- DESCRIPTER.delete_if {|n, arr| n == name }
234
- end
235
-
236
- def ConfigTable.config_key?(name)
237
- get_entry(name) ? true : false
238
- end
239
-
240
- def ConfigTable.bool_config?(name)
241
- ent = get_entry(name) or return false
242
- ent[1] == 'yes/no'
243
- end
244
-
245
- def ConfigTable.value_config?(name)
246
- ent = get_entry(name) or return false
247
- ent[1] != 'yes/no'
248
- end
249
-
250
- def ConfigTable.path_config?(name)
251
- ent = get_entry(name) or return false
252
- ent[1] == 'path'
253
- end
254
-
255
-
256
- class << self
257
- alias newobj new
258
- end
259
-
260
- def ConfigTable.new
261
- c = newobj()
262
- c.initialize_from_table
263
- c
264
- end
265
-
266
- def ConfigTable.load
267
- c = newobj()
268
- c.initialize_from_file
269
- c
270
- end
271
-
272
- def initialize_from_table
273
- @table = {}
274
- DESCRIPTER.each do |k, (default, vname, desc, default2)|
275
- @table[k] = default
276
- end
277
- end
278
-
279
- def initialize_from_file
280
- raise InstallError, "#{File.basename $0} config first"\
281
- unless File.file?(SAVE_FILE)
282
- @table = {}
283
- File.foreach(SAVE_FILE) do |line|
284
- k, v = line.split(/=/, 2)
285
- @table[k] = v.strip
286
- end
287
- end
288
-
289
- def save
290
- File.open(SAVE_FILE, 'w') {|f|
291
- @table.each do |k, v|
292
- f.printf "%s=%s\n", k, v if v
293
- end
294
- }
295
- end
296
-
297
- def []=(k, v)
298
- raise InstallError, "unknown config option #{k}"\
299
- unless ConfigTable.config_key?(k)
300
- @table[k] = v
301
- end
302
-
303
- def [](key)
304
- return nil unless @table[key]
305
- @table[key].gsub(%r<\$([^/]+)>) { self[$1] }
306
- end
307
-
308
- def set_raw(key, val)
309
- @table[key] = val
310
- end
311
-
312
- def get_raw(key)
313
- @table[key]
314
- end
315
-
316
- end
317
-
318
-
319
- module MetaConfigAPI
320
-
321
- def eval_file_ifexist(fname)
322
- instance_eval File.read(fname), fname, 1 if File.file?(fname)
323
- end
324
-
325
- def config_names
326
- ConfigTable.keys
327
- end
328
-
329
- def config?(name)
330
- ConfigTable.config_key?(name)
331
- end
332
-
333
- def bool_config?(name)
334
- ConfigTable.bool_config?(name)
335
- end
336
-
337
- def value_config?(name)
338
- ConfigTable.value_config?(name)
339
- end
340
-
341
- def path_config?(name)
342
- ConfigTable.path_config?(name)
343
- end
344
-
345
- def add_config(name, argname, default, desc)
346
- ConfigTable.add_entry name,[default,argname,desc]
347
- end
348
-
349
- def add_path_config(name, default, desc)
350
- add_config name, 'path', default, desc
351
- end
352
-
353
- def add_bool_config(name, default, desc)
354
- add_config name, 'yes/no', default ? 'yes' : 'no', desc
355
- end
356
-
357
- def set_config_default(name, default)
358
- if bool_config?(name)
359
- ConfigTable.get_entry!(name)[0] = (default ? 'yes' : 'no')
360
- else
361
- ConfigTable.get_entry!(name)[0] = default
362
- end
363
- end
364
-
365
- def remove_config(name)
366
- ent = ConfigTable.get_entry(name)
367
- ConfigTable.remove_entry name
368
- ent
369
- end
370
-
371
- end
372
-
373
- #
374
- # File Operations
375
- #
376
-
377
- module FileOperations
378
-
379
- def mkdir_p(dirname, prefix = nil)
380
- dirname = prefix + dirname if prefix
381
- $stderr.puts "mkdir -p #{dirname}" if verbose?
382
- return if no_harm?
383
-
384
- # does not check '/'... it's too abnormal case
385
- dirs = dirname.split(%r<(?=/)>)
386
- if /\A[a-z]:\z/i =~ dirs[0]
387
- disk = dirs.shift
388
- dirs[0] = disk + dirs[0]
389
- end
390
- dirs.each_index do |idx|
391
- path = dirs[0..idx].join('')
392
- Dir.mkdir path unless File.dir?(path)
393
- end
394
- end
395
-
396
- def rm_f(fname)
397
- $stderr.puts "rm -f #{fname}" if verbose?
398
- return if no_harm?
399
-
400
- if File.exist?(fname) or File.symlink?(fname)
401
- File.chmod 0777, fname
402
- File.unlink fname
403
- end
404
- end
405
-
406
- def rm_rf(dn)
407
- $stderr.puts "rm -rf #{dn}" if verbose?
408
- return if no_harm?
409
-
410
- Dir.chdir dn
411
- Dir.foreach('.') do |fn|
412
- next if fn == '.'
413
- next if fn == '..'
414
- if File.dir?(fn)
415
- verbose_off {
416
- rm_rf fn
417
- }
418
- else
419
- verbose_off {
420
- rm_f fn
421
- }
422
- end
423
- end
424
- Dir.chdir '..'
425
- Dir.rmdir dn
426
- end
427
-
428
- def move_file(src, dest)
429
- File.unlink dest if File.exist?(dest)
430
- begin
431
- File.rename src, dest
432
- rescue
433
- File.open(dest, 'wb') {|f| f.write File.binread(src) }
434
- File.chmod File.stat(src).mode, dest
435
- File.unlink src
436
- end
437
- end
438
-
439
- def install(from, dest, mode, prefix = nil)
440
- $stderr.puts "install #{from} #{dest}" if verbose?
441
- return if no_harm?
442
-
443
- realdest = prefix ? prefix + dest : dest
444
- realdest = File.join(realdest, File.basename(from)) if File.dir?(realdest)
445
- str = File.binread(from)
446
- if diff?(str, realdest)
447
- verbose_off {
448
- rm_f realdest if File.exist?(realdest)
449
- }
450
- File.open(realdest, 'wb') {|f|
451
- f.write str
452
- }
453
- File.chmod mode, realdest
454
-
455
- File.open("#{objdir_root()}/InstalledFiles", 'a') {|f|
456
- if prefix
457
- f.puts realdest.sub(prefix, '')
458
- else
459
- f.puts realdest
460
- end
461
- }
462
- end
463
- end
464
-
465
- def diff?(new_content, path)
466
- return true unless File.exist?(path)
467
- new_content != File.binread(path)
468
- end
469
-
470
- def command(str)
471
- $stderr.puts str if verbose?
472
- system str or raise RuntimeError, "'system #{str}' failed"
473
- end
474
-
475
- def ruby(str)
476
- command config('ruby-prog') + ' ' + str
477
- end
478
-
479
- def make(task = '')
480
- command config('make-prog') + ' ' + task
481
- end
482
-
483
- def extdir?(dir)
484
- File.exist?(dir + '/MANIFEST') or File.exist?("#{dir}/extconf.rb")
485
- end
486
-
487
- def all_files_in(dirname)
488
- Dir.open(dirname) {|d|
489
- return d.select {|ent| File.file?("#{dirname}/#{ent}") }
490
- }
491
- end
492
-
493
- REJECT_DIRS = %w(
494
- CVS SCCS RCS CVS.adm .svn
495
- )
496
-
497
- def all_dirs_in(dirname)
498
- Dir.open(dirname) {|d|
499
- return d.select {|n| File.dir?("#{dirname}/#{n}") } - %w(. ..) - REJECT_DIRS
500
- }
501
- end
502
-
503
- end
504
-
505
- #
506
- # Main Installer
507
- #
508
-
509
- class InstallError < StandardError; end
510
-
511
-
512
- module HookUtils
513
-
514
- def run_hook(name)
515
- try_run_hook "#{curr_srcdir()}/#{name}" or
516
- try_run_hook "#{curr_srcdir()}/#{name}.rb"
517
- end
518
-
519
- def try_run_hook(fname)
520
- return false unless File.file?(fname)
521
- begin
522
- instance_eval File.read(fname), fname, 1
523
- rescue
524
- raise InstallError, "hook #{fname} failed:\n" + $!.message
525
- end
526
- true
527
- end
528
-
529
- end
530
-
531
-
532
- module HookScriptAPI
533
-
534
- def get_config(key)
535
- @config[key]
536
- end
537
-
538
- alias config get_config
539
-
540
- def set_config(key, val)
541
- @config[key] = val
542
- end
543
-
544
- #
545
- # srcdir/objdir (works only in the package directory)
546
- #
547
-
548
- #abstract srcdir_root
549
- #abstract objdir_root
550
- #abstract relpath
551
-
552
- def curr_srcdir
553
- "#{srcdir_root()}/#{relpath()}"
554
- end
555
-
556
- def curr_objdir
557
- "#{objdir_root()}/#{relpath()}"
558
- end
559
-
560
- def srcfile(path)
561
- "#{curr_srcdir()}/#{path}"
562
- end
563
-
564
- def srcexist?(path)
565
- File.exist?(srcfile(path))
566
- end
567
-
568
- def srcdirectory?(path)
569
- File.dir?(srcfile(path))
570
- end
571
-
572
- def srcfile?(path)
573
- File.file? srcfile(path)
574
- end
575
-
576
- def srcentries(path = '.')
577
- Dir.open("#{curr_srcdir()}/#{path}") {|d|
578
- return d.to_a - %w(. ..)
579
- }
580
- end
581
-
582
- def srcfiles(path = '.')
583
- srcentries(path).select {|fname|
584
- File.file?(File.join(curr_srcdir(), path, fname))
585
- }
586
- end
587
-
588
- def srcdirectories(path = '.')
589
- srcentries(path).select {|fname|
590
- File.dir?(File.join(curr_srcdir(), path, fname))
591
- }
592
- end
593
-
594
- end
595
-
596
-
597
- class ToplevelInstaller
598
-
599
- Version = '3.3.0'
600
- Copyright = 'Copyright (c) 2000-2004 Minero Aoki'
601
-
602
- TASKS = [
603
- [ 'all', 'do config, setup, then install' ],
604
- [ 'config', 'saves your configurations' ],
605
- [ 'show', 'shows current configuration' ],
606
- [ 'setup', 'compiles ruby extentions and others' ],
607
- [ 'install', 'installs files' ],
608
- [ 'clean', "does `make clean' for each extention" ],
609
- [ 'distclean',"does `make distclean' for each extention" ]
610
- ]
611
-
612
- def ToplevelInstaller.invoke
613
- instance().invoke
614
- end
615
-
616
- @singleton = nil
617
-
618
- def ToplevelInstaller.instance
619
- @singleton ||= new(File.dirname($0))
620
- @singleton
621
- end
622
-
623
- include MetaConfigAPI
624
-
625
- def initialize(ardir_root)
626
- @config = nil
627
- @options = { 'verbose' => true }
628
- @ardir = File.expand_path(ardir_root)
629
- end
630
-
631
- def inspect
632
- "#<#{self.class} #{__id__()}>"
633
- end
634
-
635
- def invoke
636
- run_metaconfigs
637
- case task = parsearg_global()
638
- when nil, 'all'
639
- @config = load_config('config')
640
- parsearg_config
641
- init_installers
642
- exec_config
643
- exec_setup
644
- exec_install
645
- else
646
- @config = load_config(task)
647
- __send__ "parsearg_#{task}"
648
- init_installers
649
- __send__ "exec_#{task}"
650
- end
651
- end
652
-
653
- def run_metaconfigs
654
- eval_file_ifexist "#{@ardir}/metaconfig"
655
- end
656
-
657
- def load_config(task)
658
- case task
659
- when 'config'
660
- ConfigTable.new
661
- when 'clean', 'distclean'
662
- if File.exist?(ConfigTable::SAVE_FILE)
663
- then ConfigTable.load
664
- else ConfigTable.new
665
- end
666
- else
667
- ConfigTable.load
668
- end
669
- end
670
-
671
- def init_installers
672
- @installer = Installer.new(@config, @options, @ardir, File.expand_path('.'))
673
- end
674
-
675
- #
676
- # Hook Script API bases
677
- #
678
-
679
- def srcdir_root
680
- @ardir
681
- end
682
-
683
- def objdir_root
684
- '.'
685
- end
686
-
687
- def relpath
688
- '.'
689
- end
690
-
691
- #
692
- # Option Parsing
693
- #
694
-
695
- def parsearg_global
696
- valid_task = /\A(?:#{TASKS.map {|task,desc| task }.join '|'})\z/
697
-
698
- while arg = ARGV.shift
699
- case arg
700
- when /\A\w+\z/
701
- raise InstallError, "invalid task: #{arg}" unless valid_task =~ arg
702
- return arg
703
-
704
- when '-q', '--quiet'
705
- @options['verbose'] = false
706
-
707
- when '--verbose'
708
- @options['verbose'] = true
709
-
710
- when '-h', '--help'
711
- print_usage $stdout
712
- exit 0
713
-
714
- when '-v', '--version'
715
- puts "#{File.basename($0)} version #{Version}"
716
- exit 0
717
-
718
- when '--copyright'
719
- puts Copyright
720
- exit 0
721
-
722
- else
723
- raise InstallError, "unknown global option '#{arg}'"
724
- end
725
- end
726
-
727
- nil
728
- end
729
-
730
-
731
- def parsearg_no_options
732
- raise InstallError, "#{task}: unknown options: #{ARGV.join ' '}"\
733
- unless ARGV.empty?
734
- end
735
-
736
- alias parsearg_show parsearg_no_options
737
- alias parsearg_setup parsearg_no_options
738
- alias parsearg_clean parsearg_no_options
739
- alias parsearg_distclean parsearg_no_options
740
-
741
- def parsearg_config
742
- re = /\A--(#{ConfigTable.keys.join '|'})(?:=(.*))?\z/
743
- @options['config-opt'] = []
744
-
745
- while i = ARGV.shift
746
- if /\A--?\z/ =~ i
747
- @options['config-opt'] = ARGV.dup
748
- break
749
- end
750
- m = re.match(i) or raise InstallError, "config: unknown option #{i}"
751
- name, value = m.to_a[1,2]
752
- if value
753
- if ConfigTable.bool_config?(name)
754
- raise InstallError, "config: --#{name} allows only yes/no for argument"\
755
- unless /\A(y(es)?|n(o)?|t(rue)?|f(alse))\z/i =~ value
756
- value = (/\Ay(es)?|\At(rue)/i =~ value) ? 'yes' : 'no'
757
- end
758
- else
759
- raise InstallError, "config: --#{name} requires argument"\
760
- unless ConfigTable.bool_config?(name)
761
- value = 'yes'
762
- end
763
- @config[name] = value
764
- end
765
- end
766
-
767
- def parsearg_install
768
- @options['no-harm'] = false
769
- @options['install-prefix'] = ''
770
- while a = ARGV.shift
771
- case a
772
- when /\A--no-harm\z/
773
- @options['no-harm'] = true
774
- when /\A--prefix=(.*)\z/
775
- path = $1
776
- path = File.expand_path(path) unless path[0,1] == '/'
777
- @options['install-prefix'] = path
778
- else
779
- raise InstallError, "install: unknown option #{a}"
780
- end
781
- end
782
- end
783
-
784
- def print_usage(out)
785
- out.puts 'Typical Installation Procedure:'
786
- out.puts " $ ruby #{File.basename $0} config"
787
- out.puts " $ ruby #{File.basename $0} setup"
788
- out.puts " # ruby #{File.basename $0} install (may require root privilege)"
789
- out.puts
790
- out.puts 'Detailed Usage:'
791
- out.puts " ruby #{File.basename $0} <global option>"
792
- out.puts " ruby #{File.basename $0} [<global options>] <task> [<task options>]"
793
-
794
- fmt = " %-20s %s\n"
795
- out.puts
796
- out.puts 'Global options:'
797
- out.printf fmt, '-q,--quiet', 'suppress message outputs'
798
- out.printf fmt, ' --verbose', 'output messages verbosely'
799
- out.printf fmt, '-h,--help', 'print this message'
800
- out.printf fmt, '-v,--version', 'print version and quit'
801
- out.printf fmt, ' --copyright', 'print copyright and quit'
802
-
803
- out.puts
804
- out.puts 'Tasks:'
805
- TASKS.each do |name, desc|
806
- out.printf " %-10s %s\n", name, desc
807
- end
808
-
809
- out.puts
810
- out.puts 'Options for CONFIG or ALL:'
811
- ConfigTable.each_definition do |name, (default, arg, desc, default2)|
812
- out.printf " %-20s %s [%s]\n",
813
- '--'+ name + (ConfigTable.bool_config?(name) ? '' : '='+arg),
814
- desc,
815
- default2 || default
816
- end
817
- out.printf " %-20s %s [%s]\n",
818
- '--rbconfig=path', 'your rbconfig.rb to load', "running ruby's"
819
-
820
- out.puts
821
- out.puts 'Options for INSTALL:'
822
- out.printf " %-20s %s [%s]\n",
823
- '--no-harm', 'only display what to do if given', 'off'
824
- out.printf " %-20s %s [%s]\n",
825
- '--prefix', 'install path prefix', '$prefix'
826
-
827
- out.puts
828
- end
829
-
830
- #
831
- # Task Handlers
832
- #
833
-
834
- def exec_config
835
- @installer.exec_config
836
- @config.save # must be final
837
- end
838
-
839
- def exec_setup
840
- @installer.exec_setup
841
- end
842
-
843
- def exec_install
844
- @installer.exec_install
845
- end
846
-
847
- def exec_show
848
- ConfigTable.each_name do |k|
849
- v = @config.get_raw(k)
850
- if not v or v.empty?
851
- v = '(not specified)'
852
- end
853
- printf "%-10s %s\n", k, v
854
- end
855
- end
856
-
857
- def exec_clean
858
- @installer.exec_clean
859
- end
860
-
861
- def exec_distclean
862
- @installer.exec_distclean
863
- end
864
-
865
- end
866
-
867
-
868
- class ToplevelInstallerMulti < ToplevelInstaller
869
-
870
- include HookUtils
871
- include HookScriptAPI
872
- include FileOperations
873
-
874
- def initialize(ardir)
875
- super
876
- @packages = all_dirs_in("#{@ardir}/packages")
877
- raise 'no package exists' if @packages.empty?
878
- end
879
-
880
- def run_metaconfigs
881
- eval_file_ifexist "#{@ardir}/metaconfig"
882
- @packages.each do |name|
883
- eval_file_ifexist "#{@ardir}/packages/#{name}/metaconfig"
884
- end
885
- end
886
-
887
- def init_installers
888
- @installers = {}
889
- @packages.each do |pack|
890
- @installers[pack] = Installer.new(@config, @options,
891
- "#{@ardir}/packages/#{pack}",
892
- "packages/#{pack}")
893
- end
894
-
895
- with = extract_selection(config('with'))
896
- without = extract_selection(config('without'))
897
- @selected = @installers.keys.select {|name|
898
- (with.empty? or with.include?(name)) \
899
- and not without.include?(name)
900
- }
901
- end
902
-
903
- def extract_selection(list)
904
- a = list.split(/,/)
905
- a.each do |name|
906
- raise InstallError, "no such package: #{name}" \
907
- unless @installers.key?(name)
908
- end
909
- a
910
- end
911
-
912
- def print_usage(f)
913
- super
914
- f.puts 'Inluded packages:'
915
- f.puts ' ' + @packages.sort.join(' ')
916
- f.puts
917
- end
918
-
919
- #
920
- # multi-package metaconfig API
921
- #
922
-
923
- attr_reader :packages
924
-
925
- def declare_packages(list)
926
- raise 'package list is empty' if list.empty?
927
- list.each do |name|
928
- raise "directory packages/#{name} does not exist"\
929
- unless File.dir?("#{@ardir}/packages/#{name}")
930
- end
931
- @packages = list
932
- end
933
-
934
- #
935
- # Task Handlers
936
- #
937
-
938
- def exec_config
939
- run_hook 'pre-config'
940
- each_selected_installers {|inst| inst.exec_config }
941
- run_hook 'post-config'
942
- @config.save # must be final
943
- end
944
-
945
- def exec_setup
946
- run_hook 'pre-setup'
947
- each_selected_installers {|inst| inst.exec_setup }
948
- run_hook 'post-setup'
949
- end
950
-
951
- def exec_install
952
- run_hook 'pre-install'
953
- each_selected_installers {|inst| inst.exec_install }
954
- run_hook 'post-install'
955
- end
956
-
957
- def exec_clean
958
- rm_f ConfigTable::SAVE_FILE
959
- run_hook 'pre-clean'
960
- each_selected_installers {|inst| inst.exec_clean }
961
- run_hook 'post-clean'
962
- end
963
-
964
- def exec_distclean
965
- rm_f ConfigTable::SAVE_FILE
966
- run_hook 'pre-distclean'
967
- each_selected_installers {|inst| inst.exec_distclean }
968
- run_hook 'post-distclean'
969
- end
970
-
971
- #
972
- # lib
973
- #
974
-
975
- def each_selected_installers
976
- Dir.mkdir 'packages' unless File.dir?('packages')
977
- @selected.each do |pack|
978
- $stderr.puts "Processing the package `#{pack}' ..." if @options['verbose']
979
- Dir.mkdir "packages/#{pack}" unless File.dir?("packages/#{pack}")
980
- Dir.chdir "packages/#{pack}"
981
- yield @installers[pack]
982
- Dir.chdir '../..'
983
- end
984
- end
985
-
986
- def verbose?
987
- @options['verbose']
988
- end
989
-
990
- def no_harm?
991
- @options['no-harm']
992
- end
993
-
994
- end
995
-
996
-
997
- class Installer
998
-
999
- FILETYPES = %w( bin lib ext data )
1000
-
1001
- include HookScriptAPI
1002
- include HookUtils
1003
- include FileOperations
1004
-
1005
- def initialize(config, opt, srcroot, objroot)
1006
- @config = config
1007
- @options = opt
1008
- @srcdir = File.expand_path(srcroot)
1009
- @objdir = File.expand_path(objroot)
1010
- @currdir = '.'
1011
- end
1012
-
1013
- def inspect
1014
- "#<#{self.class} #{File.basename(@srcdir)}>"
1015
- end
1016
-
1017
- #
1018
- # Hook Script API bases
1019
- #
1020
-
1021
- def srcdir_root
1022
- @srcdir
1023
- end
1024
-
1025
- def objdir_root
1026
- @objdir
1027
- end
1028
-
1029
- def relpath
1030
- @currdir
1031
- end
1032
-
1033
- #
1034
- # configs/options
1035
- #
1036
-
1037
- def no_harm?
1038
- @options['no-harm']
1039
- end
1040
-
1041
- def verbose?
1042
- @options['verbose']
1043
- end
1044
-
1045
- def verbose_off
1046
- begin
1047
- save, @options['verbose'] = @options['verbose'], false
1048
- yield
1049
- ensure
1050
- @options['verbose'] = save
1051
- end
1052
- end
1053
-
1054
- #
1055
- # TASK config
1056
- #
1057
-
1058
- def exec_config
1059
- exec_task_traverse 'config'
1060
- end
1061
-
1062
- def config_dir_bin(rel)
1063
- end
1064
-
1065
- def config_dir_lib(rel)
1066
- end
1067
-
1068
- def config_dir_ext(rel)
1069
- extconf if extdir?(curr_srcdir())
1070
- end
1071
-
1072
- def extconf
1073
- opt = @options['config-opt'].join(' ')
1074
- command "#{config('ruby-prog')} #{curr_srcdir()}/extconf.rb #{opt}"
1075
- end
1076
-
1077
- def config_dir_data(rel)
1078
- end
1079
-
1080
- #
1081
- # TASK setup
1082
- #
1083
-
1084
- def exec_setup
1085
- exec_task_traverse 'setup'
1086
- end
1087
-
1088
- def setup_dir_bin(rel)
1089
- all_files_in(curr_srcdir()).each do |fname|
1090
- adjust_shebang "#{curr_srcdir()}/#{fname}"
1091
- end
1092
- end
1093
-
1094
- def adjust_shebang(path)
1095
- return if no_harm?
1096
- tmpfile = File.basename(path) + '.tmp'
1097
- begin
1098
- File.open(path, 'rb') {|r|
1099
- File.open(tmpfile, 'wb') {|w|
1100
- first = r.gets
1101
- return unless should_modify_shebang?(first)
1102
- $stderr.puts "adjusting shebang: #{File.basename(path)}" if verbose?
1103
- w.print first.sub(SHEBANG_RE, '#!' + config('ruby-path'))
1104
- w.write r.read
1105
- }
1106
- }
1107
- move_file tmpfile, File.basename(path)
1108
- ensure
1109
- File.unlink tmpfile if File.exist?(tmpfile)
1110
- end
1111
- end
1112
-
1113
- def should_modify_shebang?(line)
1114
- File.basename(config('ruby-path')) == 'ruby' or
1115
- shebang_command(line) == 'ruby'
1116
- end
1117
-
1118
- def shebang_command(line)
1119
- cmd, arg = *line.sub(/\A\#!/, '').strip.split(/\s+/, 2)
1120
- cmd
1121
- end
1122
-
1123
- def setup_dir_lib(rel)
1124
- end
1125
-
1126
- def setup_dir_ext(rel)
1127
- make if extdir?(curr_srcdir())
1128
- end
1129
-
1130
- def setup_dir_data(rel)
1131
- end
1132
-
1133
- #
1134
- # TASK install
1135
- #
1136
-
1137
- def exec_install
1138
- exec_task_traverse 'install'
1139
- end
1140
-
1141
- def install_dir_bin(rel)
1142
- install_files collect_filenames_auto(), "#{config('bin-dir')}/#{rel}", 0755
1143
- end
1144
-
1145
- def install_dir_lib(rel)
1146
- install_files ruby_scripts(), "#{config('rb-dir')}/#{rel}", 0644
1147
- end
1148
-
1149
- def install_dir_ext(rel)
1150
- return unless extdir?(curr_srcdir())
1151
- install_files ruby_extentions('.'),
1152
- "#{config('so-dir')}/#{rel}",
1153
- 0555
1154
- end
1155
-
1156
- def install_dir_data(rel)
1157
- install_files collect_filenames_auto(), "#{config('data-dir')}/#{rel}", 0644
1158
- end
1159
-
1160
- def install_files(list, dest, mode)
1161
- mkdir_p dest, @options['install-prefix']
1162
- list.each do |fname|
1163
- install fname, dest, mode, @options['install-prefix']
1164
- end
1165
- end
1166
-
1167
- def ruby_scripts
1168
- collect_filenames_auto().select {|n| /\.rb\z/ =~ n }
1169
- end
1170
-
1171
- # picked up many entries from cvs-1.11.1/src/ignore.c
1172
- reject_patterns = %w(
1173
- core RCSLOG tags TAGS .make.state
1174
- .nse_depinfo #* .#* cvslog.* ,* .del-* *.olb
1175
- *~ *.old *.bak *.BAK *.orig *.rej _$* *$
1176
-
1177
- *.org *.in .*
1178
- )
1179
- mapping = {
1180
- '.' => '\.',
1181
- '$' => '\$',
1182
- '#' => '\#',
1183
- '*' => '.*'
1184
- }
1185
- REJECT_PATTERNS = Regexp.new('\A(?:' +
1186
- reject_patterns.map {|pat|
1187
- pat.gsub(/[\.\$\#\*]/) {|ch| mapping[ch] }
1188
- }.join('|') +
1189
- ')\z')
1190
-
1191
- def collect_filenames_auto
1192
- mapdir((existfiles() - hookfiles()).reject {|fname|
1193
- REJECT_PATTERNS =~ fname
1194
- })
1195
- end
1196
-
1197
- def existfiles
1198
- all_files_in(curr_srcdir()) | all_files_in('.')
1199
- end
1200
-
1201
- def hookfiles
1202
- %w( pre-%s post-%s pre-%s.rb post-%s.rb ).map {|fmt|
1203
- %w( config setup install clean ).map {|t| sprintf(fmt, t) }
1204
- }.flatten
1205
- end
1206
-
1207
- def mapdir(filelist)
1208
- filelist.map {|fname|
1209
- if File.exist?(fname) # objdir
1210
- fname
1211
- else # srcdir
1212
- File.join(curr_srcdir(), fname)
1213
- end
1214
- }
1215
- end
1216
-
1217
- def ruby_extentions(dir)
1218
- _ruby_extentions(dir) or
1219
- raise InstallError, "no ruby extention exists: 'ruby #{$0} setup' first"
1220
- end
1221
-
1222
- DLEXT = /\.#{ ::RbConfig::CONFIG['DLEXT'] }\z/
1223
-
1224
- def _ruby_extentions(dir)
1225
- Dir.open(dir) {|d|
1226
- return d.select {|fname| DLEXT =~ fname }
1227
- }
1228
- end
1229
-
1230
- #
1231
- # TASK clean
1232
- #
1233
-
1234
- def exec_clean
1235
- exec_task_traverse 'clean'
1236
- rm_f ConfigTable::SAVE_FILE
1237
- rm_f 'InstalledFiles'
1238
- end
1239
-
1240
- def clean_dir_bin(rel)
1241
- end
1242
-
1243
- def clean_dir_lib(rel)
1244
- end
1245
-
1246
- def clean_dir_ext(rel)
1247
- return unless extdir?(curr_srcdir())
1248
- make 'clean' if File.file?('Makefile')
1249
- end
1250
-
1251
- def clean_dir_data(rel)
1252
- end
1253
-
1254
- #
1255
- # TASK distclean
1256
- #
1257
-
1258
- def exec_distclean
1259
- exec_task_traverse 'distclean'
1260
- rm_f ConfigTable::SAVE_FILE
1261
- rm_f 'InstalledFiles'
1262
- end
1263
-
1264
- def distclean_dir_bin(rel)
1265
- end
1266
-
1267
- def distclean_dir_lib(rel)
1268
- end
1269
-
1270
- def distclean_dir_ext(rel)
1271
- return unless extdir?(curr_srcdir())
1272
- make 'distclean' if File.file?('Makefile')
1273
- end
1274
-
1275
- #
1276
- # lib
1277
- #
1278
-
1279
- def exec_task_traverse(task)
1280
- run_hook "pre-#{task}"
1281
- FILETYPES.each do |type|
1282
- if config('without-ext') == 'yes' and type == 'ext'
1283
- $stderr.puts 'skipping ext/* by user option' if verbose?
1284
- next
1285
- end
1286
- traverse task, type, "#{task}_dir_#{type}"
1287
- end
1288
- run_hook "post-#{task}"
1289
- end
1290
-
1291
- def traverse(task, rel, mid)
1292
- dive_into(rel) {
1293
- run_hook "pre-#{task}"
1294
- __send__ mid, rel.sub(%r[\A.*?(?:/|\z)], '')
1295
- all_dirs_in(curr_srcdir()).each do |d|
1296
- traverse task, "#{rel}/#{d}", mid
1297
- end
1298
- run_hook "post-#{task}"
1299
- }
1300
- end
1301
-
1302
- def dive_into(rel)
1303
- return unless File.dir?("#{@srcdir}/#{rel}")
1304
-
1305
- dir = File.basename(rel)
1306
- Dir.mkdir dir unless File.dir?(dir)
1307
- prevdir = Dir.pwd
1308
- Dir.chdir dir
1309
- $stderr.puts '---> ' + rel if verbose?
1310
- @currdir = rel
1311
- yield
1312
- Dir.chdir prevdir
1313
- $stderr.puts '<--- ' + rel if verbose?
1314
- @currdir = File.dirname(rel)
1315
- end
1316
-
1317
- end
1318
-
1319
-
1320
- if $0 == __FILE__
1321
- begin
1322
- if multipackage_install?
1323
- ToplevelInstallerMulti.invoke
1324
- else
1325
- ToplevelInstaller.invoke
1326
- end
1327
- rescue
1328
- raise if $DEBUG
1329
- $stderr.puts $!.message
1330
- $stderr.puts "Try 'ruby #{$0} --help' for detailed usage."
1331
- exit 1
1332
- end
1333
- end