inifile 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/README.txt +5 -2
- data/lib/inifile.rb +74 -25
- data/test/data/browscap.ini +5 -0
- data/test/data/good.ini +3 -1
- data/test/data/multiline.ini +17 -0
- data/test/test_inifile.rb +38 -2
- metadata +59 -17
- data/.gitignore +0 -17
data/History.txt
CHANGED
data/README.txt
CHANGED
@@ -31,6 +31,8 @@ A typical INI file might look like this:
|
|
31
31
|
; some comment on section1
|
32
32
|
var1 = foo
|
33
33
|
var2 = doodle
|
34
|
+
var3 = "multiline
|
35
|
+
also possible"
|
34
36
|
|
35
37
|
[section2]
|
36
38
|
|
@@ -38,12 +40,13 @@ A typical INI file might look like this:
|
|
38
40
|
var1 = baz
|
39
41
|
var2 = shoodle
|
40
42
|
|
43
|
+
|
41
44
|
==== Format
|
42
45
|
|
43
46
|
This describes the elements of the INI file format:
|
44
47
|
|
45
48
|
* *Sections*: Section declarations start with '[' and end with ']' as in [section1] and [section2] above. And sections start with section declarations.
|
46
|
-
* *Parameters*: The "var1 = foo" above is an example of a parameter (also known as an item). Parameters are made up of a key ('var1'), equals sign ('='), and a value ('foo').
|
49
|
+
* *Parameters*: The "var1 = foo" above is an example of a parameter (also known as an item). Parameters are made up of a key ('var1'), equals sign ('='), and a value ('foo'). Multiline is support if value of parameter is enclosed by ".
|
47
50
|
* *Comments*: All the lines starting with a ';' are assumed to be comments, and are ignored.
|
48
51
|
|
49
52
|
==== Differences
|
@@ -64,7 +67,7 @@ This package supports the standard INI file format described in the *Format*
|
|
64
67
|
section above. The following differences are also supported:
|
65
68
|
|
66
69
|
* *Comments*: The comment character can be specified when an +IniFile+ is created. The comment character must be the first non-whitespace character on a line.
|
67
|
-
* *Backslashes*: Backslashes are not supported by this package.
|
70
|
+
* *Backslashes*: Backslashes are not supported by this package. But multilines are. Enclose the param's value by ".
|
68
71
|
* <b>Duplicate parameters</b>: Duplicate parameters are allowed in a single section. The last parameter value is the one that will be stored in the +IniFile+.
|
69
72
|
* <b>Duplicate sections</b>: Duplicate sections will be merged. Parameters duplicated between to the two sections follow the duplicate parameters rule above.
|
70
73
|
* *Parameters*: The parameter separator character can be specified when an +IniFile+ is created.
|
data/lib/inifile.rb
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
# This class represents the INI file and can be used to parse, modify,
|
3
3
|
# and write INI files.
|
4
4
|
#
|
5
|
+
|
6
|
+
#encoding: UTF-8
|
7
|
+
|
5
8
|
class IniFile
|
6
9
|
|
7
10
|
# Inifile is enumerable.
|
@@ -9,7 +12,7 @@ class IniFile
|
|
9
12
|
|
10
13
|
# :stopdoc:
|
11
14
|
class Error < StandardError; end
|
12
|
-
VERSION = '0.
|
15
|
+
VERSION = '0.4.0'
|
13
16
|
# :startdoc:
|
14
17
|
|
15
18
|
#
|
@@ -38,16 +41,22 @@ class IniFile
|
|
38
41
|
#
|
39
42
|
# :comment => ';' The line comment character(s)
|
40
43
|
# :parameter => '=' The parameter / value separator
|
44
|
+
# :encoding => nil The encoding used for read/write (RUBY 1.9)
|
41
45
|
#
|
42
46
|
def initialize( filename, opts = {} )
|
43
47
|
@fn = filename
|
44
48
|
@comment = opts[:comment] || ';#'
|
45
49
|
@param = opts[:parameter] || '='
|
50
|
+
@encoding = opts[:encoding]
|
46
51
|
@ini = Hash.new {|h,k| h[k] = Hash.new}
|
47
52
|
|
48
53
|
@rgxp_comment = %r/\A\s*\z|\A\s*[#{@comment}]/
|
49
54
|
@rgxp_section = %r/\A\s*\[([^\]]+)\]/o
|
50
|
-
@rgxp_param = %r/\A([^#{@param}]+)#{@param}(
|
55
|
+
@rgxp_param = %r/\A([^#{@param}]+)#{@param}\s*"?([^"]*)"?\z/
|
56
|
+
|
57
|
+
@rgxp_multiline_start = %r/\A([^#{@param}]+)#{@param}\s*"+([^"]*)?\z/
|
58
|
+
@rgxp_multiline_value = %r/\A([^"]*)\z/
|
59
|
+
@rgxp_multiline_end = %r/\A([^"]*)"\z/
|
51
60
|
|
52
61
|
parse
|
53
62
|
end
|
@@ -60,11 +69,19 @@ class IniFile
|
|
60
69
|
# Write the INI file contents to the filesystem. The given _filename_
|
61
70
|
# will be used to write the file. If _filename_ is not given, then the
|
62
71
|
# named used when constructing this object will be used.
|
72
|
+
# The following _options_ can be passed to this method:
|
73
|
+
#
|
74
|
+
# :encoding => nil The encoding used for writing (RUBY 1.9)
|
63
75
|
#
|
64
|
-
def write( filename = nil )
|
76
|
+
def write( filename = nil, opts={} )
|
65
77
|
@fn = filename unless filename.nil?
|
66
78
|
|
67
|
-
|
79
|
+
encoding = opts[:encoding] || @encoding
|
80
|
+
mode = (RUBY_VERSION >= '1.9' && @encoding) ?
|
81
|
+
"w:#{encoding.to_s}" :
|
82
|
+
'w'
|
83
|
+
|
84
|
+
File.open(@fn, mode) do |f|
|
68
85
|
@ini.each do |section,hash|
|
69
86
|
f.puts "[#{section}]"
|
70
87
|
hash.each {|param,val| f.puts "#{param} #{@param} #{val}"}
|
@@ -279,34 +296,66 @@ class IniFile
|
|
279
296
|
#
|
280
297
|
def parse
|
281
298
|
return unless File.file?(@fn)
|
299
|
+
|
282
300
|
section = nil
|
301
|
+
tmp_value = ""
|
302
|
+
tmp_param = ""
|
303
|
+
|
304
|
+
fd = (RUBY_VERSION >= '1.9' && @encoding) ?
|
305
|
+
File.open(@fn, 'r', :encoding => @encoding) :
|
306
|
+
File.open(@fn, 'r')
|
307
|
+
|
308
|
+
while line = fd.gets
|
309
|
+
line = line.chomp
|
310
|
+
|
311
|
+
# mutline start
|
312
|
+
# create tmp variables to indicate that a multine has started
|
313
|
+
# and the next lines of the ini file will be checked
|
314
|
+
# against the other mutline rgxps.
|
315
|
+
if line =~ @rgxp_multiline_start then
|
283
316
|
|
284
|
-
|
285
|
-
|
286
|
-
line = line.chomp
|
317
|
+
tmp_param = $1.strip
|
318
|
+
tmp_value = $2 + "\n"
|
287
319
|
|
288
|
-
|
289
|
-
|
290
|
-
|
320
|
+
# the mutline end-delimiter is found
|
321
|
+
# clear the tmp vars and add the param / value pair to the section
|
322
|
+
elsif line =~ @rgxp_multiline_end && tmp_param != "" then
|
291
323
|
|
292
|
-
|
293
|
-
|
324
|
+
section[tmp_param] = tmp_value + $1
|
325
|
+
tmp_value, tmp_param = "", ""
|
294
326
|
|
295
|
-
|
296
|
-
|
297
|
-
begin
|
298
|
-
section[$1.strip] = $2.strip
|
299
|
-
rescue NoMethodError
|
300
|
-
raise Error, "parameter encountered before first section"
|
301
|
-
end
|
327
|
+
# anything else between multiline start and end
|
328
|
+
elsif line =~ @rgxp_multiline_value && tmp_param != "" then
|
302
329
|
|
303
|
-
|
304
|
-
|
330
|
+
tmp_value += $1 + "\n"
|
331
|
+
|
332
|
+
# ignore blank lines and comment lines
|
333
|
+
elsif line =~ @rgxp_comment then
|
334
|
+
|
335
|
+
next
|
336
|
+
|
337
|
+
# this is a section declaration
|
338
|
+
elsif line =~ @rgxp_section then
|
339
|
+
|
340
|
+
section = @ini[$1.strip]
|
341
|
+
|
342
|
+
# otherwise we have a parameter
|
343
|
+
elsif line =~ @rgxp_param then
|
344
|
+
|
345
|
+
begin
|
346
|
+
section[$1.strip] = $2.strip
|
347
|
+
rescue NoMethodError
|
348
|
+
raise Error, "parameter encountered before first section"
|
305
349
|
end
|
306
|
-
|
307
|
-
|
350
|
+
|
351
|
+
else
|
352
|
+
raise Error, "could not parse line '#{line}"
|
353
|
+
end
|
354
|
+
end # while
|
355
|
+
|
356
|
+
ensure
|
357
|
+
fd.close if defined? fd and fd
|
308
358
|
end
|
309
359
|
|
310
|
-
end #
|
360
|
+
end # IniFile
|
311
361
|
|
312
|
-
# EOF
|
data/test/data/good.ini
CHANGED
data/test/test_inifile.rb
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
# classname: asrt / meth = ratio%
|
3
3
|
# Rini::IniFile: 0 / 9 = 0.00%
|
4
4
|
|
5
|
+
# encoding: UTF-8
|
6
|
+
|
5
7
|
begin
|
6
8
|
require 'inifile'
|
7
9
|
rescue LoadError
|
@@ -22,6 +24,7 @@ class TestIniFile < Test::Unit::TestCase
|
|
22
24
|
['section_one', 'one', '1'],
|
23
25
|
['section_one', 'two', '2'],
|
24
26
|
['section_two', 'three', '3'],
|
27
|
+
['section_two', 'multi', "multiline\nsupport"],
|
25
28
|
['section three', 'four', '4'],
|
26
29
|
['section three', 'five', '5'],
|
27
30
|
['section three', 'six', '6'],
|
@@ -192,7 +195,7 @@ class TestIniFile < Test::Unit::TestCase
|
|
192
195
|
}
|
193
196
|
assert_equal expected, @ini_file[:section_one]
|
194
197
|
|
195
|
-
expected = {'three' => '3'}
|
198
|
+
expected = {'three' => '3', 'multi' => "multiline\nsupport"}
|
196
199
|
assert_equal expected, @ini_file['section_two']
|
197
200
|
|
198
201
|
expected = {
|
@@ -330,6 +333,39 @@ class TestIniFile < Test::Unit::TestCase
|
|
330
333
|
ini_file[:foo] = {}
|
331
334
|
assert_equal ini_file["foo"], {}
|
332
335
|
end
|
336
|
+
|
337
|
+
def test_multiline_parsing
|
338
|
+
ini_file = IniFile.load('test/data/multiline.ini')
|
339
|
+
|
340
|
+
multiline = ini_file['section_three']
|
341
|
+
expected = {"three" => "hello\nmultiline", "other" => "stuff"}
|
342
|
+
assert_equal expected, multiline
|
343
|
+
|
344
|
+
multiple = ini_file['section_four']
|
345
|
+
expected = {"four" => "hello\nmultiple\nmultilines"}
|
346
|
+
assert_equal expected, multiple
|
347
|
+
|
348
|
+
end
|
349
|
+
|
350
|
+
if RUBY_VERSION >= '1.9'
|
351
|
+
def test_parse_encoding
|
352
|
+
ini_file = IniFile.new("test/data/browscap.ini", :encoding => 'ISO-8859-1')
|
353
|
+
assert_equal ini_file['www.substancia.com AutoHTTPAgent (ver *)']['Browser'], "Subst\xE2ncia".force_encoding('ISO-8859-1')
|
354
|
+
end
|
355
|
+
|
356
|
+
def test_write_encoding
|
357
|
+
tmp = 'test/data/tmp.ini'
|
358
|
+
File.delete tmp if Kernel.test(?f, tmp)
|
359
|
+
|
360
|
+
@ini_file = IniFile.new(tmp, :encoding => 'UTF-8')
|
361
|
+
@ini_file['testutf-8'] = {"utf-8" => "appr\u20accier"}
|
362
|
+
|
363
|
+
@ini_file.save tmp
|
364
|
+
|
365
|
+
test = File.open(tmp)
|
366
|
+
assert_equal test.external_encoding.to_s, 'UTF-8'
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
333
370
|
end
|
334
371
|
|
335
|
-
# EOF
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inifile
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 15
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 4
|
9
|
+
- 0
|
10
|
+
version: 0.4.0
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- Tim Pease
|
@@ -9,30 +15,59 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2011-02-15 00:00:00 -07:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
22
|
name: bones-git
|
17
|
-
|
18
|
-
|
19
|
-
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
20
26
|
requirements:
|
21
27
|
- - ">="
|
22
28
|
- !ruby/object:Gem::Version
|
23
|
-
|
24
|
-
|
29
|
+
hash: 23
|
30
|
+
segments:
|
31
|
+
- 1
|
32
|
+
- 2
|
33
|
+
- 4
|
34
|
+
version: 1.2.4
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
25
37
|
- !ruby/object:Gem::Dependency
|
26
38
|
name: bones
|
27
|
-
|
28
|
-
|
29
|
-
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
30
42
|
requirements:
|
31
43
|
- - ">="
|
32
44
|
- !ruby/object:Gem::Version
|
33
|
-
|
34
|
-
|
35
|
-
|
45
|
+
hash: 21
|
46
|
+
segments:
|
47
|
+
- 3
|
48
|
+
- 6
|
49
|
+
- 5
|
50
|
+
version: 3.6.5
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
53
|
+
description: |-
|
54
|
+
This is a native Ruby package for reading and writing INI files.
|
55
|
+
|
56
|
+
Although made popular by Windows, INI files can be used on any system thanks
|
57
|
+
to their flexibility. They allow a program to store configuration data, which
|
58
|
+
can then be easily parsed and changed. Two notable systems that use the INI
|
59
|
+
format are Samba and Trac.
|
60
|
+
|
61
|
+
== SYNOPSIS:
|
62
|
+
|
63
|
+
An initialization file, or INI file, is a configuration file that contains
|
64
|
+
configuration data for Microsoft Windows based applications. Starting with
|
65
|
+
Windows 95, the INI file format was superseded but not entirely replaced by
|
66
|
+
a registry database in Microsoft operating systems.
|
67
|
+
|
68
|
+
Although made popular by Windows, INI files can be used on any system thanks
|
69
|
+
to their flexibility. They allow a program to store configuration data, which
|
70
|
+
can then be easily parsed and changed.
|
36
71
|
email: tim.pease@gmail.com
|
37
72
|
executables: []
|
38
73
|
|
@@ -42,16 +77,17 @@ extra_rdoc_files:
|
|
42
77
|
- History.txt
|
43
78
|
- README.txt
|
44
79
|
files:
|
45
|
-
- .gitignore
|
46
80
|
- History.txt
|
47
81
|
- README.txt
|
48
82
|
- Rakefile
|
49
83
|
- lib/inifile.rb
|
50
84
|
- test/data/bad_1.ini
|
51
85
|
- test/data/bad_2.ini
|
86
|
+
- test/data/browscap.ini
|
52
87
|
- test/data/comment.ini
|
53
88
|
- test/data/good.ini
|
54
89
|
- test/data/mixed_comment.ini
|
90
|
+
- test/data/multiline.ini
|
55
91
|
- test/data/param.ini
|
56
92
|
- test/test_inifile.rb
|
57
93
|
has_rdoc: true
|
@@ -65,21 +101,27 @@ rdoc_options:
|
|
65
101
|
require_paths:
|
66
102
|
- lib
|
67
103
|
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
68
105
|
requirements:
|
69
106
|
- - ">="
|
70
107
|
- !ruby/object:Gem::Version
|
108
|
+
hash: 3
|
109
|
+
segments:
|
110
|
+
- 0
|
71
111
|
version: "0"
|
72
|
-
version:
|
73
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
74
114
|
requirements:
|
75
115
|
- - ">="
|
76
116
|
- !ruby/object:Gem::Version
|
117
|
+
hash: 3
|
118
|
+
segments:
|
119
|
+
- 0
|
77
120
|
version: "0"
|
78
|
-
version:
|
79
121
|
requirements: []
|
80
122
|
|
81
123
|
rubyforge_project: inifile
|
82
|
-
rubygems_version: 1.3.
|
124
|
+
rubygems_version: 1.3.7
|
83
125
|
signing_key:
|
84
126
|
specification_version: 3
|
85
127
|
summary: INI file reader and writer
|
data/.gitignore
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# The list of files that should be ignored by Mr Bones.
|
2
|
-
# Lines that start with '#' are comments.
|
3
|
-
#
|
4
|
-
# A .gitignore file can be used instead by setting it as the ignore
|
5
|
-
# file in your Rakefile:
|
6
|
-
#
|
7
|
-
# PROJ.ignore_file = '.gitignore'
|
8
|
-
#
|
9
|
-
# For a project with a C extension, the following would be a good set of
|
10
|
-
# exclude patterns (uncomment them if you want to use them):
|
11
|
-
# *.[oa]
|
12
|
-
*~
|
13
|
-
*.sw[op]
|
14
|
-
announcement.txt
|
15
|
-
coverage
|
16
|
-
doc
|
17
|
-
pkg
|