alib 0.3.1 → 0.4.0

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.
@@ -0,0 +1,113 @@
1
+ #
2
+ # yaml configfile class
3
+ #
4
+ class ALib::ConfigFile < ::Hash
5
+ #--{{{
6
+ DEFAULT_CONIFG = {}
7
+ DEFAULT_SEARCH_PATH = %w(. ~ /usr/local/etc /usr/etc /etc)
8
+ DEFAULT_BASENAME = ".#{ File::basename $0 }.conf"
9
+
10
+ class << self
11
+ #--{{{
12
+ attr :config, true
13
+ attr :search_path, true
14
+ attr :basename, true
15
+ attr :default_text, true
16
+ def init
17
+ #--{{{
18
+ @config = DEFAULT_CONIFG
19
+ @search_path = DEFAULT_SEARCH_PATH
20
+ @basename = DEFAULT_BASENAME
21
+ #--}}}
22
+ end
23
+ def gen_template port = nil
24
+ #--{{{
25
+ port ||= STDOUT
26
+ buf = @default_text || @config.to_yaml
27
+ if port.respond_to? 'write'
28
+ port.write buf
29
+ port.write "\n"
30
+ else
31
+ open("#{ port }", 'w'){|f| f.puts buf}
32
+ end
33
+ #--}}}
34
+ end
35
+ def default= conf
36
+ #--{{{
37
+ if conf.respond_to?('read')
38
+ @default_text = munge conf.read
39
+ @config = YAML::load @default_text
40
+ else
41
+ case conf
42
+ when Hash
43
+ @config = conf
44
+ when Pathname
45
+ open(conf) do |f|
46
+ @default_text = munge f.read
47
+ @config = YAML::load @default_text
48
+ end
49
+ when String
50
+ @default_text = munge conf
51
+ @config = YAML::load @default_text
52
+ end
53
+ end
54
+ @config
55
+ #--}}}
56
+ end
57
+ alias set_default default=
58
+ def default(*a)
59
+ #--{{{
60
+ if a.empty?
61
+ @config ||= {}
62
+ else
63
+ self.default= a.first
64
+ end
65
+ #--}}}
66
+ end
67
+ def any(basename = @basename, *dirnames)
68
+ #--{{{
69
+ config = nil
70
+ dirnames = @search_path if dirnames.empty?
71
+ dirnames.each do |dirname|
72
+ path = File::join dirname, basename
73
+ path = File::expand_path path
74
+ if test ?e, path
75
+ config = self::new path
76
+ break
77
+ end
78
+ end
79
+ config || self::new('default')
80
+ #--}}}
81
+ end
82
+ def munge buf
83
+ #--{{{
84
+ buf.gsub(%r/\t/o,' ')
85
+ #--}}}
86
+ end
87
+ #--}}}
88
+ end
89
+ self.init
90
+
91
+ attr :path
92
+ def initialize path = 'default'
93
+ #--{{{
94
+ @path = nil
95
+ yaml = nil
96
+ if path.nil? or path and path =~ /^\s*default/io
97
+ yaml = self.class.default
98
+ @path = 'DEFAULT'
99
+ else path
100
+ yaml = YAML::load(self.class.munge(open(path).read))
101
+ @path = path
102
+ end
103
+ self.update yaml
104
+ #--}}}
105
+ end
106
+ def to_hash
107
+ #--{{{
108
+ {}.update self
109
+ #--}}}
110
+ end
111
+ #--}}}
112
+ end # class ConfigFile
113
+ ALib::Configfile = ALib::ConfigFile
@@ -0,0 +1,294 @@
1
+ # -*- Ruby -*-
2
+ # Copyright (C) 1998, 2001 Motoyuki Kasahara
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2, or (at your option)
7
+ # any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ #
15
+ # Traverse a file tree, replacement of `find.rb'.
16
+ #
17
+ class ALib::Find2
18
+ #--{{{
19
+ #
20
+ # Constatnts
21
+ #
22
+ FIND1 = 1
23
+ FIND2 = 2
24
+ #
25
+ # Initializer.
26
+ #
27
+ def initialize(mode = FIND1)
28
+ #--{{{
29
+ @mode = mode
30
+ @depth = false
31
+ @follow = false
32
+ @xdev = false
33
+
34
+ @dirname_stats = Array.new
35
+ @found_files = Array.new
36
+ @target_device = 0
37
+
38
+ @handle = lambda { |file, stat_result, block|
39
+ case @mode
40
+ when FIND1
41
+ block ? block.call(file) : @found_files.push(file)
42
+ when FIND2
43
+ block ? block.call(file, stat_result) : @found_files.push([file, stat_result])
44
+ end
45
+ }
46
+ #--}}}
47
+ end
48
+ #
49
+ # Methods for accessing instances.
50
+ #
51
+ attr :depth
52
+ attr :follow
53
+ attr :xdev
54
+ #
55
+ # Find the directory `dirname'. (private)
56
+ #
57
+ def find(*arguments, &block)
58
+ #--{{{
59
+ #
60
+ # Parse options if specified.
61
+ #
62
+ #if arguments[0].type == Hash
63
+ #parse_options(arguments.shift)
64
+ #end
65
+
66
+ # hack
67
+ args = []
68
+ opts = []
69
+ arguments.each do |arg|
70
+ case arg
71
+ when Hash
72
+ opts << arg
73
+ else
74
+ args << arg
75
+ end
76
+ end
77
+ opts.each{|opt| parse_options opt}
78
+ files = args.flatten.compact
79
+
80
+ #
81
+ # If a block is not given to the `find' method, found files are
82
+ # recorded in this array.
83
+ #
84
+ @dirname_stats.clear
85
+ @found_files.clear
86
+
87
+ #
88
+ # Loop for each file in `files'.
89
+ #
90
+ files.each do |file|
91
+ catch(:prune) do
92
+ @dirname_stats.clear
93
+
94
+ #
95
+ # Get `stat' or `lstat' of `file'.
96
+ #
97
+ begin
98
+ if @follow
99
+ begin
100
+ stat_result = File.stat(file)
101
+ rescue Errno::ENOENT, Errno::EACCES
102
+ stat_result = File.lstat(file)
103
+ end
104
+ else
105
+ stat_result = File.lstat(file)
106
+ end
107
+ rescue Errno::ENOENT, Errno::EACCES
108
+ next
109
+ end
110
+
111
+ #
112
+ # Push `file' to the found stack, or yield with it,
113
+ # if the depth flag is enabled.
114
+ #
115
+ @handle[ file, stat_result, block ] if !@depth
116
+
117
+ #
118
+ # If `file' is a directory, find files recursively.
119
+ #
120
+ if stat_result.directory?
121
+ @xdev_device = stat_result.dev if @xdev
122
+ @dirname_stats.push(stat_result)
123
+ find_directory(file, block)
124
+ end
125
+
126
+ #
127
+ # Push `file' to the found stack, or yield with it.
128
+ # if the depth flag is disabled.
129
+ #
130
+ @handle[ file, stat_result, block ] if @depth
131
+
132
+ end
133
+ end
134
+
135
+ if block == nil
136
+ return @found_files
137
+ else
138
+ return nil
139
+ end
140
+ #--}}}
141
+ end
142
+ #
143
+ # Find the directory `dirname'. (private)
144
+ #
145
+ def find_directory(dirname, block)
146
+ #--{{{
147
+ #
148
+ # Open the directory `dirname'.
149
+ #
150
+ begin
151
+ dir = Dir.open(dirname)
152
+ rescue
153
+ return
154
+ end
155
+
156
+ #
157
+ # Read all directory entries except for `.' and `..'.
158
+ #
159
+ entries = Array.new
160
+ loop do
161
+ begin
162
+ entry = dir.read
163
+ rescue
164
+ break
165
+ end
166
+ break if entry == nil
167
+ next if entry == '.' || entry == '..'
168
+ entries.push(entry)
169
+ end
170
+
171
+ #
172
+ # Close `dir'.
173
+ #
174
+ dir.close
175
+
176
+ #
177
+ # Loop for each entry in this directory.
178
+ #
179
+ catch(:prune) do
180
+ entries.each do |entry|
181
+ #
182
+ # Set `entry_path' to the full path of `entry'.
183
+ #
184
+ if dirname[-1, 1] == File::Separator
185
+ entry_path = dirname + entry
186
+ else
187
+ entry_path = dirname + File::Separator + entry
188
+ end
189
+
190
+ #
191
+ # Get `stat' or `lstat' of `entry_path'.
192
+ #
193
+ begin
194
+ if @follow
195
+ begin
196
+ stat_result = File.stat(entry_path)
197
+ rescue Errno::ENOENT, Errno::EACCES
198
+ stat_result = File.lstat(entry_path)
199
+ end
200
+ else
201
+ stat_result = File.lstat(entry_path)
202
+ end
203
+ rescue Errno::ENOENT, Errno::EACCES
204
+ next
205
+ end
206
+
207
+ #
208
+ # Push `entry_path' to the found stack, or yield with it,
209
+ # if the depth flag is enabled.
210
+ #
211
+
212
+ @handle[ entry_path, stat_result, block ] if !@depth
213
+
214
+ #
215
+ # If `entry_path' is a directory, find recursively.
216
+ #
217
+ if stat_result.directory? \
218
+ && (!@xdev || @xdev_device == stat_result.dev) \
219
+ && (!@follow || !visited?(stat_result))
220
+ @dirname_stats.push(stat_result)
221
+ find_directory(entry_path, block)
222
+ @dirname_stats.pop
223
+ end
224
+
225
+ #
226
+ # Push `entry_path' to the found stack, or yield with it,
227
+ # if the depth flag is disabled.
228
+ #
229
+ @handle[ entry_path, stat_result, block ] if @depth
230
+
231
+ end
232
+ end
233
+ #--}}}
234
+ end
235
+ private :find_directory
236
+ #
237
+ # Find the directory `dirname'. (class method)
238
+ #
239
+ def self.find(*arguments, &block)
240
+ new.find(*arguments, &block)
241
+ end
242
+ #
243
+ # Find the directory `dirname'. (class method)
244
+ #
245
+ def self.find2(*arguments, &block)
246
+ new(FIND2).find(*arguments, &block)
247
+ end
248
+ #
249
+ # Parse options.
250
+ #
251
+ def parse_options(options)
252
+ #--{{{
253
+ return if options == nil
254
+
255
+ options.each_pair do |key, value|
256
+ case "#{ key }".strip.downcase
257
+ when 'depth'
258
+ @depth = value
259
+ when 'follow'
260
+ @follow = value
261
+ when 'xdev'
262
+ @xdev = value
263
+ else
264
+ raise ArgumentError, "unknown option - #{key}"
265
+ end
266
+ end
267
+ #--}}}
268
+ end
269
+ private :parse_options
270
+ #
271
+ # Prune the current visited directory.
272
+ #
273
+ def self.prune
274
+ #--{{{
275
+ throw :prune
276
+ #--}}}
277
+ end
278
+ #
279
+ # Did we visit the directory with the resouce `stat'? (private)
280
+ #
281
+ def visited?(stat_result)
282
+ #--{{{
283
+ dev = stat_result.dev
284
+ ino = stat_result.ino
285
+ @dirname_stats.each do |i|
286
+ return TRUE if i.dev == dev && i.ino == ino
287
+ end
288
+ return FALSE
289
+ #--}}}
290
+ end
291
+ private :visited?
292
+ #--}}}
293
+ end # class Find2
294
+ ALib::Find = ALib::Find2
@@ -0,0 +1,42 @@
1
+ #
2
+ # file of lines, comments and blank lines are ignored
3
+ #
4
+ class ALib::ListFile < ::Array
5
+ #--{{{
6
+ class << self
7
+ #--{{{
8
+ def parse arg, &b
9
+ #--{{{
10
+ arg.respond_to?('gets') ? loadio(arg, &b) : open(arg.to_s){|f| loadio(f, &b)}
11
+ #--}}}
12
+ end
13
+ def loadio io
14
+ #--{{{
15
+ while((line = io.gets))
16
+ line.gsub!(%r/#.*/o,'')
17
+ next if line =~ %r/^[^\S]+$/o
18
+ line.gsub!(%r/^[^\S]+|[^\S]+$/o,'')
19
+ yield line
20
+ end
21
+ #--}}}
22
+ end
23
+ #--}}}
24
+ end
25
+ attr :path
26
+ def initialize arg
27
+ #--{{{
28
+ case arg
29
+ when Pathname, String
30
+ @path = path
31
+ self.class.parse(arg){|line| self << line}
32
+ when IO
33
+ @path = arg.respond_to?('path') ? arg.path : arg.to_s
34
+ self.class.loadio(arg){|line| self << line}
35
+ else
36
+ raise "cannot initialize from <#{ arg.inspect }>"
37
+ end
38
+ #--}}}
39
+ end
40
+ #--}}}
41
+ end # class ListFile
42
+ ALib::Listfile = ALib::ListFile