inifile 0.3.0 → 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.
@@ -1,3 +1,9 @@
1
+ == 0.4.0 / 2011-02-
2
+
3
+ Enhancements
4
+ - Added multiline support [André Gawron]
5
+ - Added file encoding support [Gilles Devaux]
6
+
1
7
  == 0.3.0 / 2009-12-10
2
8
 
3
9
  * 1 minor enhancement
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.
@@ -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.3.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}(.*)\z/
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
- File.open(@fn, 'w') do |f|
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
- File.open(@fn, 'r') do |f|
285
- while line = f.gets
286
- line = line.chomp
317
+ tmp_param = $1.strip
318
+ tmp_value = $2 + "\n"
287
319
 
288
- case line
289
- # ignore blank lines and comment lines
290
- when @rgxp_comment; next
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
- # this is a section declaration
293
- when @rgxp_section; section = @ini[$1.strip]
324
+ section[tmp_param] = tmp_value + $1
325
+ tmp_value, tmp_param = "", ""
294
326
 
295
- # otherwise we have a parameter
296
- when @rgxp_param
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
- else
304
- raise Error, "could not parse line '#{line}"
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
- end # while
307
- end # File.open
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 # class IniFile
360
+ end # IniFile
311
361
 
312
- # EOF
@@ -0,0 +1,5 @@
1
+
2
+ ;just the offending entry
3
+ [www.substancia.com AutoHTTPAgent (ver *)]
4
+ Parent=Version Checkers
5
+ Browser=Subst�ncia
@@ -3,7 +3,9 @@ one = 1
3
3
  two = 2
4
4
 
5
5
  [section_two]
6
- three = 3
6
+ three = 3
7
+ multi = "multiline
8
+ support"
7
9
 
8
10
  ; comments should be ignored
9
11
  [section three]
@@ -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
+ three = "hello
11
+ multiline"
12
+ other = "stuff"
13
+
14
+ [section_four]
15
+ four = "hello
16
+ multiple
17
+ multilines"
@@ -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
- version: 0.3.0
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: 2009-12-10 00:00:00 -07:00
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
- type: :development
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
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
- version: 1.1.1
24
- version:
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
- type: :development
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
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
- version: 3.2.0
34
- version:
35
- description: This is a native Ruby package for reading and writing INI files.
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.5
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