ini 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,113 @@
1
+
2
+ = Conventional INI File Parsing and Writing
3
+
4
+ == Introduction
5
+
6
+ Ah yes, INI files. We love them. We hate them. We cannot escape
7
+ them. Originally made popular by Windows, INI files are everywhere
8
+ including in Samba[www.samba.org] and Trac[trac.edgewall.org]. This
9
+ gem has one goal: make INI file, structure, and stream manipulation
10
+ as fast, safe, and simple as possible. We take a modal approach
11
+ with a pluggable parser class.
12
+
13
+ == Sample File
14
+
15
+ ; some comment about section1
16
+ [section1]
17
+ var1 = foo
18
+ var2 = doodle
19
+
20
+ [section2]
21
+
22
+ ; some comment about var1
23
+ var1 = baz
24
+
25
+ ; some comment about var2
26
+ var2 = shoodle
27
+
28
+ == Conventional Format
29
+
30
+ There is no formal INI specification but most parsers observe the
31
+ following so we do also by default:
32
+
33
+ === Sections
34
+
35
+ Section declarations are wrapped in square brackets
36
+ (<tt>[section1]</tt>) with no spaces surrounding the section
37
+ name. Duplicate sections are discouraged but if included are merged.
38
+
39
+ === Parameters
40
+
41
+ The <tt>var1 = foo</tt> above is an example of a parameter, also
42
+ frequently referred to a property, item, or pair. Each parameter is
43
+ made up of a key name (<tt>var1</tt>), an equals sign (<tt>=</tt>),
44
+ and a value (<tt>foo</tt>) with optional spaces. Leading spaces
45
+ before the key name are allowed and leading spaces before or after
46
+ the value are trimmed. Values are literally the characters that
47
+ remain, even if quoted (<tt>var1 = "foo"</tt> would include the
48
+ quotes in the value). Duplicate parameters, either in the same
49
+ section or merged duplicate sections, play 'last one wins'.
50
+
51
+ === Comments
52
+
53
+ All lines starting with a semicolon (<tt>;</tt>) are assumed to be
54
+ comments and are ignored. This character must be the first on the line.
55
+
56
+ === Blank Lines
57
+
58
+ All lines that contain nothing but spaces are ignored.
59
+
60
+ === Line Endings
61
+
62
+ Lines end at either a CRLF or just a LF (CR=\015, LF=\012). Files
63
+ may mix the two within the same file to accomodate edits from
64
+ different platforms.
65
+
66
+ === Format Variations Supported
67
+
68
+ Because INI format is not formally specified, many variations exist
69
+ in the wild. Some of these are supported by extra parsers that are
70
+ included and set by changing the <tt>mode</tt> of the <ini> instance.
71
+
72
+ To maintain backward compatibility with the original 'inifile' gem,
73
+ the following variations are supported by the default parser:
74
+
75
+ * <b>Comments:</b> the comment character can be specified when an instance is created
76
+ * <b>Parameters:</b> separator character can be specified when an instance is created
77
+ * <b>Duplicate Sections:</b> merged
78
+ * <b>Duplicate Parameters:</b> the last one wins
79
+
80
+ === Currently Unsupported Format Variations
81
+
82
+ If it isn't listed above, chances are it isn't supported. But here
83
+ are some specific variations in case you are wondering (and, yes,
84
+ we do have plans eventually support them, either as defaults or options):
85
+
86
+ * Parameter value continuation with backslash (<tt>\\</tt>)
87
+ * Parameter value double-quoting with escapes (<tt>foo = "value with \\n in it"</tt>)
88
+ * Parameter values using braces (<tt>{}</tt>)
89
+ * Parameter values using simple commas parsing into arrays
90
+
91
+ == Copyright and License
92
+
93
+ Copyright (c) 2006-2007 The 'ini' and 'inifile' Gem Team
94
+
95
+ Permission is hereby granted, free of charge, to any person obtaining
96
+ a copy of this software and associated documentation files (the
97
+ "Software"), to deal in the Software without restriction, including
98
+ without limitation the rights to use, copy, modify, merge, publish,
99
+ distribute, sublicense, and/or sell copies of the Software, and to
100
+ permit persons to whom the Software is furnished to do so, subject to
101
+ the following conditions:
102
+
103
+ The above copyright notice and this permission notice shall be
104
+ included in all copies or substantial portions of the Software.
105
+
106
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
107
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
108
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
109
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
110
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
111
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
112
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
113
+
@@ -0,0 +1,264 @@
1
+ # $Id: ini.rb 1 2007-01-17 15:21:30Z ironmo $
2
+
3
+ #
4
+ # This class represents the INI file and can be used to parse, modify,
5
+ # and write INI files.
6
+ #
7
+ class Ini
8
+
9
+ # :stopdoc:
10
+ class Error < StandardError; end
11
+ # :startdoc:
12
+
13
+ #
14
+ # call-seq:
15
+ # IniFile.load( filename )
16
+ # IniFile.load( filename, options )
17
+ #
18
+ # Open the given _filename_ and load the contetns of the INI file.
19
+ # The following _options_ can be passed to this method:
20
+ #
21
+ # :comment => ';' The line comment character(s)
22
+ # :parameter => '=' The parameter / value separator
23
+ #
24
+ def self.load( filename, opts = {} )
25
+ new(filename, opts)
26
+ end
27
+
28
+ #
29
+ # call-seq:
30
+ # IniFile.new( filename )
31
+ # IniFile.new( filename, options )
32
+ #
33
+ # Create a new INI file using the given _filename_. If _filename_
34
+ # exists and is a regular file, then its contents will be parsed.
35
+ # The following _options_ can be passed to this method:
36
+ #
37
+ # :comment => ';' The line comment character(s)
38
+ # :parameter => '=' The parameter / value separator
39
+ #
40
+ def initialize( filename, opts = {} )
41
+ @fn = filename
42
+ @comment = opts[:comment] || ';'
43
+ @param = opts[:parameter] || '='
44
+ @ini = Hash.new {|h,k| h[k] = Hash.new}
45
+
46
+ @rgxp_comment = %r/\A\s*\z|\A\s*[#{@comment}]/
47
+ @rgxp_section = %r/\A\s*\[([^\]]+)\]/o
48
+ @rgxp_param = %r/\A([^#{@param}]+)#{@param}(.*)\z/
49
+
50
+ parse
51
+ end
52
+
53
+ #
54
+ # call-seq:
55
+ # write
56
+ # write( filename )
57
+ #
58
+ # Write the INI file contents to the filesystem. The given _filename_
59
+ # will be used to write the file. If _filename_ is not given, then the
60
+ # named used when constructing this object will be used.
61
+ #
62
+ def write( filename = nil )
63
+ @fn = filename unless filename.nil?
64
+
65
+ ::File.open(@fn, 'w') do |f|
66
+ @ini.each do |section,hash|
67
+ f.puts "[#{section}]"
68
+ hash.each {|param,val| f.puts "#{param} #{@param} #{val}"}
69
+ f.puts
70
+ end
71
+ end
72
+ self
73
+ end
74
+ alias :save :write
75
+
76
+ #
77
+ # call-seq:
78
+ # each {|section, parameter, value| block}
79
+ #
80
+ # Yield each _section_, _parameter_, _value_ in turn to the given
81
+ # _block_. The method returns immediately if no block is supplied.
82
+ #
83
+ def each
84
+ return unless block_given?
85
+ @ini.each do |section,hash|
86
+ hash.each do |param,val|
87
+ yield section, param, val
88
+ end
89
+ end
90
+ self
91
+ end
92
+
93
+ #
94
+ # call-seq:
95
+ # each_section {|section| block}
96
+ #
97
+ # Yield each _section_ in turn to the given _block_. The method returns
98
+ # immediately if no block is supplied.
99
+ #
100
+ def each_section
101
+ return unless block_given?
102
+ @ini.each_key {|section| yield section}
103
+ self
104
+ end
105
+
106
+ #
107
+ # call-seq:
108
+ # delete_section( section )
109
+ #
110
+ # Deletes the named _section_ from the INI file. Returns the
111
+ # parameter / value pairs if the section exists in the INI file. Otherwise,
112
+ # returns +nil+.
113
+ #
114
+ def delete_section( section )
115
+ @ini.delete section.to_s
116
+ end
117
+
118
+ #
119
+ # call-seq:
120
+ # ini_file[section]
121
+ #
122
+ # Get the hash of parameter/value pairs for the given _section_. If the
123
+ # _section_ hash does not exist it will be created.
124
+ #
125
+ def []( section )
126
+ return nil if section.nil?
127
+ @ini[section.to_s]
128
+ end
129
+
130
+ #
131
+ # call-seq:
132
+ # has_section?( section )
133
+ #
134
+ # Returns +true+ if the named _section_ exists in the INI file.
135
+ #
136
+ def has_section?( section )
137
+ @ini.has_key? section.to_s
138
+ end
139
+
140
+ #
141
+ # call-seq:
142
+ # sections
143
+ #
144
+ # Returns an array of the section names.
145
+ #
146
+ def sections
147
+ @ini.keys
148
+ end
149
+
150
+ #
151
+ # call-seq:
152
+ # freeze
153
+ #
154
+ # Freeze the state of the +IniFile+ object. Any attempts to change the
155
+ # object will raise an error.
156
+ #
157
+ def freeze
158
+ super
159
+ @ini.each_value {|h| h.freeze}
160
+ @ini.freeze
161
+ self
162
+ end
163
+
164
+ #
165
+ # call-seq:
166
+ # taint
167
+ #
168
+ # Marks the INI file as tainted -- this will traverse each section marking
169
+ # each section as tainted as well.
170
+ #
171
+ def taint
172
+ super
173
+ @ini.each_value {|h| h.taint}
174
+ @ini.taint
175
+ self
176
+ end
177
+
178
+ #
179
+ # call-seq:
180
+ # dup
181
+ #
182
+ # Produces a duplicate of this INI file. The duplicate is independent of the
183
+ # original -- i.e. the duplicate can be modified without changing the
184
+ # orgiinal. The tainted state of the original is copied to the duplicate.
185
+ #
186
+ def dup
187
+ other = super
188
+ other.instance_variable_set(:@ini, Hash.new {|h,k| h[k] = Hash.new})
189
+ @ini.each_pair {|s,h| other[s].merge! h}
190
+ other.taint if self.tainted?
191
+ other
192
+ end
193
+
194
+ #
195
+ # call-seq:
196
+ # clone
197
+ #
198
+ # Produces a duplicate of this INI file. The duplicate is independent of the
199
+ # original -- i.e. the duplicate can be modified without changing the
200
+ # orgiinal. The tainted state and the frozen state of the original is copied
201
+ # to the duplicate.
202
+ #
203
+ def clone
204
+ other = dup
205
+ other.freeze if self.frozen?
206
+ other
207
+ end
208
+
209
+ #
210
+ # call-seq:
211
+ # eql?( other )
212
+ #
213
+ # Returns +true+ if the _other_ object is equivalent to this INI file. For
214
+ # two INI files to be equivalent, they must have the same sections with the
215
+ # same parameter / value pairs in each section.
216
+ #
217
+ def eql?( other )
218
+ return true if equal? other
219
+ return false unless other.instance_of? self.class
220
+ @ini == other.instance_variable_get(:@ini)
221
+ end
222
+ alias :== :eql?
223
+
224
+
225
+ private
226
+ #
227
+ # call-seq
228
+ # parse
229
+ #
230
+ # Parse the ini file contents.
231
+ #
232
+ def parse
233
+ return unless ::Kernel.test ?f, @fn
234
+ section = nil
235
+
236
+ ::File.open(@fn, 'r') do |f|
237
+ while line = f.gets
238
+ line = line.chomp
239
+
240
+ case line
241
+ # ignore blank lines and comment lines
242
+ when @rgxp_comment: next
243
+
244
+ # this is a section declaration
245
+ when @rgxp_section: section = @ini[$1.strip]
246
+
247
+ # otherwise we have a parameter
248
+ when @rgxp_param
249
+ begin
250
+ section[$1.strip] = $2.strip
251
+ rescue NoMethodError
252
+ raise Error, "parameter encountered before first section"
253
+ end
254
+
255
+ else
256
+ raise Error, "could not parse line '#{line}"
257
+ end
258
+ end # while
259
+ end # File.open
260
+ end
261
+
262
+ end
263
+
264
+ # EOF
@@ -0,0 +1,10 @@
1
+ # $Id: inifile.rb 1 2007-01-17 15:21:30Z ironmo $
2
+
3
+ # The 'inifile' gem will eventually be deprecated in favor of the
4
+ # 'ini' gem as it becomes able to handle streams, stringio and string buffers of INI
5
+ # formatted data.
6
+
7
+ require 'ini'
8
+
9
+ class IniFile < Ini
10
+ end
@@ -0,0 +1,6 @@
1
+ ; having a paramater / value pair outside a section is an error
2
+ one = 1
3
+
4
+ [section_one]
5
+ one = 1
6
+ two = 2
@@ -0,0 +1,6 @@
1
+ [section_one]
2
+ one = 1
3
+ two = 2
4
+
5
+ ; the following is not a valid line
6
+ invalid line
@@ -0,0 +1,5 @@
1
+ # comments should be ignored
2
+ [section_one]
3
+ one = 1
4
+ two = 2
5
+
@@ -0,0 +1,17 @@
1
+ [section_one]
2
+ one = 1
3
+ two = 2
4
+
5
+ [section_two]
6
+ three = 3
7
+
8
+ ; comments should be ignored
9
+ [section three]
10
+ four =4
11
+ five=5
12
+ six =6
13
+
14
+ [section_four]
15
+ [section_five]
16
+ seven and eight= 7 & 8
17
+
@@ -0,0 +1,7 @@
1
+ # comments should be ignored
2
+ ; multiple comments characeters are supported
3
+ ; (I'm lookin' at you, samba)
4
+ [section_one]
5
+ one = 1
6
+ two = 2
7
+
@@ -0,0 +1,5 @@
1
+ ; comments should be ignored
2
+ [section_one]
3
+ one : 1
4
+ two:2
5
+
@@ -0,0 +1,277 @@
1
+ # Code Generated by ZenTest v. 3.3.0
2
+ # classname: asrt / meth = ratio%
3
+ # Rini::IniFile: 0 / 9 = 0.00%
4
+
5
+ begin
6
+ require 'inifile'
7
+ rescue LoadError
8
+ require 'rubygems'
9
+ require 'inifile'
10
+ end
11
+
12
+ begin; require 'turn'; rescue LoadError; end
13
+ require 'test/unit' unless defined? $ZENTEST and $ZENTEST
14
+
15
+ class TestIniFile < Test::Unit::TestCase
16
+
17
+ def setup
18
+ @ini_file = ::IniFile.new 'test/data/good.ini'
19
+ @contents = [
20
+ ['section_one', 'one', '1'],
21
+ ['section_one', 'two', '2'],
22
+ ['section_two', 'three', '3'],
23
+ ['section three', 'four', '4'],
24
+ ['section three', 'five', '5'],
25
+ ['section three', 'six', '6'],
26
+ ['section_five', 'seven and eight', '7 & 8']
27
+ ].sort
28
+ end
29
+
30
+ def test_class_load
31
+ ini_file = ::IniFile.load 'test/data/good.ini'
32
+ assert_instance_of ::IniFile, ini_file
33
+
34
+ # see if we can parse different style comments
35
+ assert_raise(::IniFile::Error) {::IniFile.load 'test/data/comment.ini'}
36
+
37
+ ini_file = ::IniFile.load 'test/data/comment.ini', :comment => '#'
38
+ assert_instance_of ::IniFile, ini_file
39
+
40
+ # see if we can parse mixed style comments
41
+ assert_raise(::IniFile::Error) {::IniFile.load 'test/data/mixed_comment.ini'}
42
+
43
+ ini_file = ::IniFile.load 'test/data/mixed_comment.ini', :comment => ';#'
44
+ assert_instance_of ::IniFile, ini_file
45
+
46
+ # see if we can parse different style param separators
47
+ assert_raise(::IniFile::Error) {::IniFile.load 'test/data/param.ini'}
48
+
49
+ ini_file = ::IniFile.load 'test/data/param.ini', :parameter => ':'
50
+ assert_instance_of ::IniFile, ini_file
51
+
52
+ # make sure we error out on files with bad lines
53
+ assert_raise(::IniFile::Error) {::IniFile.load 'test/data/bad_1.ini'}
54
+ assert_raise(::IniFile::Error) {::IniFile.load 'test/data/bad_2.ini'}
55
+ end
56
+
57
+ def test_clone
58
+ clone = @ini_file.clone
59
+ assert_equal @ini_file, clone
60
+ assert !clone.tainted?
61
+ assert !clone.frozen?
62
+
63
+ # the clone should be completely independent of the original
64
+ clone['new_section']['one'] = 1
65
+ assert_not_equal @ini_file, clone
66
+
67
+ # the tainted state is copied to clones
68
+ @ini_file.taint
69
+ assert @ini_file.tainted?
70
+
71
+ clone = @ini_file.clone
72
+ assert clone.tainted?
73
+
74
+ # the frozen state is also copied to clones
75
+ @ini_file.freeze
76
+ assert @ini_file.frozen?
77
+
78
+ clone = @ini_file.clone
79
+ assert clone.tainted?
80
+ assert clone.frozen?
81
+ end
82
+
83
+ def test_delete_section
84
+ assert_nil @ini_file.delete_section('section_nil')
85
+
86
+ h = {'one' => '1', 'two' => '2'}
87
+ assert_equal true, @ini_file.has_section?('section_one')
88
+ assert_equal h, @ini_file.delete_section('section_one')
89
+ assert_equal false, @ini_file.has_section?('section_one')
90
+ assert_nil @ini_file.delete_section('section_one')
91
+ end
92
+
93
+ def test_dup
94
+ dup = @ini_file.dup
95
+ assert_equal @ini_file, dup
96
+ assert !dup.tainted?
97
+ assert !dup.frozen?
98
+
99
+ # the duplicate should be completely independent of the original
100
+ dup['new_section']['one'] = 1
101
+ assert_not_equal @ini_file, dup
102
+
103
+ # the tainted state is copied to duplicates
104
+ @ini_file.taint
105
+ assert @ini_file.tainted?
106
+
107
+ dup = @ini_file.dup
108
+ assert dup.tainted?
109
+
110
+ # the frozen state, however, is not
111
+ @ini_file.freeze
112
+ assert @ini_file.frozen?
113
+
114
+ dup = @ini_file.dup
115
+ assert dup.tainted?
116
+ assert !dup.frozen?
117
+ end
118
+
119
+ def test_each
120
+ ary = []
121
+ @ini_file.each {|*args| ary << args}
122
+
123
+ assert_equal @contents, ary.sort
124
+
125
+ ary = []
126
+ ::IniFile.new('temp.ini').each {|*args| ary << args}
127
+ assert_equal [], ary
128
+ end
129
+
130
+ def test_each_section
131
+ expected = [
132
+ 'section_one', 'section_two', 'section three',
133
+ 'section_four', 'section_five'
134
+ ].sort
135
+
136
+ ary = []
137
+ @ini_file.each_section {|section| ary << section}
138
+
139
+ assert_equal expected, ary.sort
140
+
141
+ ary = []
142
+ ::IniFile.new('temp.ini').each_section {|section| ary << section}
143
+ assert_equal [], ary
144
+ end
145
+
146
+ def test_eql_eh
147
+ assert @ini_file.eql?(@ini_file)
148
+ assert @ini_file.eql?(@ini_file.clone)
149
+ assert !@ini_file.eql?('string')
150
+ assert !@ini_file.eql?(IniFile.new(''))
151
+ end
152
+
153
+ def test_freeze
154
+ assert_equal false, @ini_file.frozen?
155
+ @ini_file.each_section do |s|
156
+ assert_equal false, @ini_file[s].frozen?
157
+ end
158
+
159
+ @ini_file.freeze
160
+
161
+ assert_equal true, @ini_file.frozen?
162
+ @ini_file.each_section do |s|
163
+ assert_equal true, @ini_file[s].frozen?
164
+ end
165
+ end
166
+
167
+ def test_has_section_eh
168
+ assert_equal true, @ini_file.has_section?('section_one')
169
+ assert_equal false, @ini_file.has_section?('section_ten')
170
+ assert_equal true, @ini_file.has_section?(:section_two)
171
+ assert_equal false, @ini_file.has_section?(nil)
172
+
173
+ ini_file = ::IniFile.new 'temp.ini'
174
+ assert_equal false, ini_file.has_section?('section_one')
175
+ assert_equal false, ini_file.has_section?('one')
176
+ assert_equal false, ini_file.has_section?('two')
177
+ end
178
+
179
+ def test_index
180
+ expected = {
181
+ 'one' => '1',
182
+ 'two' => '2'
183
+ }
184
+ assert_equal expected, @ini_file[:section_one]
185
+
186
+ expected = {'three' => '3'}
187
+ assert_equal expected, @ini_file['section_two']
188
+
189
+ expected = {
190
+ 'four' => '4',
191
+ 'five' => '5',
192
+ 'six' => '6',
193
+ }
194
+ assert_equal expected, @ini_file['section three']
195
+
196
+ expected = {}
197
+ assert_equal expected, @ini_file['section_four']
198
+
199
+ expected = {'seven and eight' => '7 & 8'}
200
+ assert_equal expected, @ini_file['section_five']
201
+
202
+ expected = {}
203
+ assert_equal expected, @ini_file['section_six']
204
+
205
+ assert_nil @ini_file[nil]
206
+
207
+ expected = {}
208
+ ini_file = ::IniFile.new 'temp.ini'
209
+ assert_equal expected, ini_file['section_one']
210
+ assert_equal expected, ini_file['one']
211
+ assert_nil ini_file[nil]
212
+ end
213
+
214
+ def test_initialize
215
+ # see if we can parse different style comments
216
+ assert_raise(::IniFile::Error) {::IniFile.new 'test/data/comment.ini'}
217
+
218
+ ini_file = ::IniFile.new 'test/data/comment.ini', :comment => '#'
219
+ assert_equal true, ini_file.has_section?('section_one')
220
+
221
+ # see if we can parse different style param separators
222
+ assert_raise(::IniFile::Error) {::IniFile.new 'test/data/param.ini'}
223
+
224
+ ini_file = ::IniFile.new 'test/data/param.ini', :parameter => ':'
225
+ assert_equal true, ini_file.has_section?('section_one')
226
+ assert_equal '1', ini_file['section_one']['one']
227
+ assert_equal '2', ini_file['section_one']['two']
228
+
229
+ # make sure we error out on files with bad lines
230
+ assert_raise(::IniFile::Error) {::IniFile.new 'test/data/bad_1.ini'}
231
+ assert_raise(::IniFile::Error) {::IniFile.new 'test/data/bad_2.ini'}
232
+ end
233
+
234
+ def test_sections
235
+ expected = [
236
+ 'section_one', 'section_two', 'section three',
237
+ 'section_four', 'section_five'
238
+ ].sort
239
+
240
+ assert_equal expected, @ini_file.sections.sort
241
+
242
+ ini_file = ::IniFile.new 'temp.ini'
243
+ assert_equal [], ini_file.sections
244
+ end
245
+
246
+ def test_taint
247
+ assert_equal false, @ini_file.tainted?
248
+ @ini_file.each_section do |s|
249
+ assert_equal false, @ini_file[s].tainted?
250
+ end
251
+
252
+ @ini_file.taint
253
+
254
+ assert_equal true, @ini_file.tainted?
255
+ @ini_file.each_section do |s|
256
+ assert_equal true, @ini_file[s].tainted?
257
+ end
258
+ end
259
+
260
+ def test_write
261
+ tmp = 'test/data/temp.ini'
262
+ ::File.delete tmp if ::Kernel.test(?f, tmp)
263
+
264
+ @ini_file.save tmp
265
+ assert_equal true, ::Kernel.test(?f, tmp)
266
+
267
+ ::File.delete tmp if ::Kernel.test(?f, tmp)
268
+
269
+ ini_file = ::IniFile.new tmp
270
+ ini_file.save
271
+ assert_nil ::Kernel.test(?s, tmp)
272
+
273
+ ::File.delete tmp if ::Kernel.test(?f, tmp)
274
+ end
275
+ end
276
+
277
+ # EOF
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.1
3
+ specification_version: 1
4
+ name: ini
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.1.1
7
+ date: 2007-01-17 00:00:00 -05:00
8
+ summary: INI file reader and writer
9
+ require_paths:
10
+ - lib
11
+ - test
12
+ email: inifile-talk@rubyforge.org
13
+ homepage:
14
+ rubyforge_project: inifile
15
+ description: "Ah yes, INI files. We love them. We hate them. We cannot escape them. Originally
16
+ made popular by Windows, INI files are everywhere including in Samba and Trac.
17
+ This gem has one goal: make INI file, structure, and stream manipulation as
18
+ fast, safe, and simple as possible. We take a modal approach with a pluggable
19
+ parser class."
20
+ autorequire: ini
21
+ default_executable:
22
+ bindir: bin
23
+ has_rdoc: true
24
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
25
+ requirements:
26
+ -
27
+ - ">"
28
+ - !ruby/object:Gem::Version
29
+ version: 0.0.0
30
+ version:
31
+ platform: ruby
32
+ signing_key:
33
+ cert_chain:
34
+ post_install_message:
35
+ authors:
36
+ - Rob Muhlestein
37
+ - Tim Pease
38
+ files:
39
+ - README
40
+ - lib/ini.rb
41
+ - lib/inifile.rb
42
+ - test/data/bad_1.ini
43
+ - test/data/bad_2.ini
44
+ - test/data/comment.ini
45
+ - test/data/good.ini
46
+ - test/data/mixed_comment.ini
47
+ - test/data/param.ini
48
+ - test/test_inifile.rb
49
+ test_files:
50
+ - test/test_inifile.rb
51
+ rdoc_options: []
52
+ extra_rdoc_files:
53
+ - README
54
+ executables: []
55
+ extensions: []
56
+ requirements: []
57
+ dependencies: []