actionio-inifile 2.0.3

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.
Files changed (3) hide show
  1. data/README.md +193 -0
  2. data/lib/inifile.rb +554 -0
  3. metadata +64 -0
data/README.md ADDED
@@ -0,0 +1,193 @@
1
+ inifile [![Build Status](https://secure.travis-ci.org/TwP/inifile.png)](http://travis-ci.org/TwP/inifile)
2
+ =======
3
+
4
+ This is a native Ruby package for reading and writing INI files.
5
+
6
+
7
+ Description
8
+ -----------
9
+
10
+ Although made popular by Windows, INI files can be used on any system thanks
11
+ to their flexibility. They allow a program to store configuration data, which
12
+ can then be easily parsed and changed. Two notable systems that use the INI
13
+ format are Samba and Trac.
14
+
15
+ More information about INI files can be found on the [Wikipedia Page](http://en.wikipedia.org/wiki/INI_file).
16
+
17
+ ### Properties
18
+
19
+ The basic element contained in an INI file is the property. Every property has
20
+ a name and a value, delimited by an equals sign *=*. The name appears to the
21
+ left of the equals sign and the value to the right.
22
+
23
+ name=value
24
+
25
+ ### Sections
26
+
27
+ Section declarations start with *[* and end with *]* as in `[section1]` and
28
+ `[section2]` shown in the example below. The section declaration marks the
29
+ beginning of a section. All properties after the section declaration will be
30
+ associated with that section.
31
+
32
+ ### Comments
33
+
34
+ All lines beginning with a semicolon *;* or a number sign *#* are considered
35
+ to be comments. Comment lines are ignored when parsing INI files.
36
+
37
+ ### Example File Format
38
+
39
+ A typical INI file might look like this:
40
+
41
+ [section1]
42
+ ; some comment on section1
43
+ var1 = foo
44
+ var2 = doodle
45
+ var3 = multiline values \
46
+ are also possible
47
+
48
+ [section2]
49
+ # another comment
50
+ var1 = baz
51
+ var2 = shoodle
52
+
53
+
54
+ Implementation
55
+ --------------
56
+
57
+ The format of INI files is not well defined. Several assumptions are made by
58
+ the **inifile** gem when parsing INI files. Most of these assumptions can be
59
+ modified at, but the defaults are listed below.
60
+
61
+ ### Global Properties
62
+
63
+ If the INI file lacks any section declarations, or if there are properties
64
+ decalared before the first section, then these properties will be placed into
65
+ a default "global" section. The name of this section can be configured when
66
+ creating an `IniFile` instance.
67
+
68
+ ### Duplicate Properties
69
+
70
+ Duplicate properties are allowed in a single section. The last property value
71
+ set is the one that will be stored in the `IniFile` instance.
72
+
73
+ [section1]
74
+ var1 = foo
75
+ var2 = bar
76
+ var1 = poodle
77
+
78
+ The resulting value of `var1` will be `poodle`.
79
+
80
+ ### Duplicate Sections
81
+
82
+ If you have more than one section with the same name then the sections will be
83
+ merged. Duplicate properties between the two sections will follow the rules
84
+ discussed above. Properties in the latter section will override properties in
85
+ the earlier section.
86
+
87
+ ### Comments
88
+
89
+ The comment character can be either a semicolon *;* or a number sign *#*. The
90
+ comment character can appear anywhere on a line including at the end of a
91
+ name/value pair declaration. If you wish to use a comment character in your
92
+ value then you will need to either escape the character or put the value in
93
+ double quotations.
94
+
95
+ [section1]
96
+ var1 = foo # a comment
97
+ var2 = "foo # this is not a comment"
98
+ var3 = foo \# this is not a comment either
99
+
100
+ ### Multi-Line Values
101
+
102
+ Values can be continued onto multiple lines in two separate ways. Putting a
103
+ slash at the end of a line will continue the value declaration to the next
104
+ line. When parsing, the trailing slash will be consumed and **will not**
105
+ appear in the resulting value. Comments can appear to the right of the
106
+ trailing slash.
107
+
108
+ var1 = this is a \ # these comments will
109
+ multiline value # be ignored by the parser
110
+
111
+ In the above example the resulting value for `var1` will be `this is a
112
+ multiline value`. If you want to preserve newline characters in the value then
113
+ quotations should be used.
114
+
115
+ var2 = "this is a
116
+ multiline value"
117
+
118
+ The resulting value for `var2` will be `this is a\nmultiline value`.
119
+
120
+ ### Escape Characters
121
+
122
+ Several escape characters are supported within the **value** for a property.
123
+ These escape sequences will be applied to quoted and unquoted values alike.
124
+ You can enable or disable escaping by setting the **escape** flag to true or
125
+ false when creating an IniFile instance.
126
+
127
+ * \0 -- null character
128
+ * \n -- newline character
129
+ * \r -- carriage return character
130
+ * \t -- tab character
131
+ * \\\\ -- backslash character
132
+
133
+ The backslash escape sequence is only needed if you want one of the escape
134
+ sequences to appear literally in your value. For example:
135
+
136
+ property = this is not a tab \\t character
137
+
138
+
139
+ Install
140
+ -------
141
+
142
+ gem install inifile
143
+
144
+
145
+ Testing
146
+ -------
147
+
148
+ To run the tests:
149
+
150
+ $ rake
151
+
152
+
153
+ Contributing
154
+ ------------
155
+
156
+ Contributions are gladly welcome! For small modifications (fixing typos,
157
+ improving documentation) you can use GitHub's in-browser editing capabilities
158
+ to create a pull request. For larger modifications I would recommend forking
159
+ the project, creating your patch, and then submitting a pull request.
160
+
161
+ Mr Bones is used to manage rake tasks and to install dependent files. To setup
162
+ your environment ...
163
+
164
+ $ gem install bones
165
+ $ rake gem:install_dependencies
166
+
167
+ And always remember that `rake -T` will show you the list of available tasks.
168
+
169
+
170
+ License
171
+ -------
172
+
173
+ MIT License
174
+ Copyright (c) 2006 - 2012
175
+
176
+ Permission is hereby granted, free of charge, to any person obtaining
177
+ a copy of this software and associated documentation files (the
178
+ 'Software'), to deal in the Software without restriction, including
179
+ without limitation the rights to use, copy, modify, merge, publish,
180
+ distribute, sublicense, and/or sell copies of the Software, and to
181
+ permit persons to whom the Software is furnished to do so, subject to
182
+ the following conditions:
183
+
184
+ The above copyright notice and this permission notice shall be
185
+ included in all copies or substantial portions of the Software.
186
+
187
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
188
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
189
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
190
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
191
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
192
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
193
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/lib/inifile.rb ADDED
@@ -0,0 +1,554 @@
1
+ #encoding: UTF-8
2
+ require 'strscan'
3
+
4
+ # This class represents the INI file and can be used to parse, modify,
5
+ # and write INI files.
6
+ #
7
+ class IniFile
8
+ include Enumerable
9
+
10
+ class Error < StandardError; end
11
+ VERSION = '2.0.2'
12
+
13
+ # Public: Open an INI file and load the contents.
14
+ #
15
+ # filename - The name of the fiel as a String
16
+ # opts - The Hash of options (default: {})
17
+ # :comment - String containing the comment character(s)
18
+ # :parameter - String used to separate parameter and value
19
+ # :encoding - Encoding String for reading / writing (Ruby 1.9)
20
+ # :escape - Boolean used to control character escaping
21
+ # :default - The String name of the default global section
22
+ #
23
+ # Examples
24
+ #
25
+ # IniFile.load('file.ini')
26
+ # #=> IniFile instance
27
+ #
28
+ # IniFile.load('does/not/exist.ini')
29
+ # #=> nil
30
+ #
31
+ # Returns an IniFile intsnace or nil if the file could not be opened.
32
+ #
33
+ def self.load( filename, opts = {} )
34
+ return unless File.file? filename
35
+ new(opts.merge(:filename => filename))
36
+ end
37
+
38
+ # Get and set the filename
39
+ attr_accessor :filename
40
+
41
+ # Get and set the encoding (Ruby 1.9)
42
+ attr_accessor :encoding
43
+
44
+ # Enable or disable character escaping
45
+ attr_accessor :escape
46
+
47
+ # Public: Create a new INI file from the given content String which
48
+ # contains the INI file lines. If the content are omitted, then the
49
+ # :filename option is used to read in the content of the INI file. If
50
+ # neither the content for a filename is provided then an empty INI file is
51
+ # created.
52
+ #
53
+ # content - The String containing the INI file contents
54
+ # opts - The Hash of options (default: {})
55
+ # :comment - String containing the comment character(s)
56
+ # :parameter - String used to separate parameter and value
57
+ # :encoding - Encoding String for reading / writing (Ruby 1.9)
58
+ # :escape - Boolean used to control character escaping
59
+ # :default - The String name of the default global section
60
+ # :filename - The filename as a String
61
+ #
62
+ # Examples
63
+ #
64
+ # IniFile.new
65
+ # #=> an empty IniFile instance
66
+ #
67
+ # IniFile.new( "[global]\nfoo=bar" )
68
+ # #=> an IniFile instance
69
+ #
70
+ # IniFile.new( :filename => 'file.ini', :encoding => 'UTF-8' )
71
+ # #=> an IniFile instance
72
+ #
73
+ # IniFile.new( "[global]\nfoo=bar", :comment => '#' )
74
+ # #=> an IniFile instance
75
+ #
76
+ def initialize( content = nil, opts = {} )
77
+ opts, content = content, nil if Hash === content
78
+
79
+ @content = content
80
+
81
+ @comment = opts.fetch(:comment, ';#')
82
+ @param = opts.fetch(:parameter, '=')
83
+ @encoding = opts.fetch(:encoding, nil)
84
+ @escape = opts.fetch(:escape, true)
85
+ @default = opts.fetch(:default, 'global')
86
+ @filename = opts.fetch(:filename, nil)
87
+
88
+ @ini = Hash.new {|h,k| h[k] = Hash.new}
89
+
90
+ if @content then parse!
91
+ elsif @filename then read
92
+ end
93
+ end
94
+
95
+ # Public: Write the contents of this IniFile to the file system. If left
96
+ # unspecified, the currently configured filename and encoding will be used.
97
+ # Otherwise the filename and encoding can be specified in the options hash.
98
+ #
99
+ # opts - The default options Hash
100
+ # :filename - The filename as a String
101
+ # :encoding - The encoding as a String (Ruby 1.9)
102
+ #
103
+ # Returns this IniFile instance.
104
+ #
105
+ def write( opts = {} )
106
+ filename = opts.fetch(:filename, @filename)
107
+ encoding = opts.fetch(:encoding, @encoding)
108
+ mode = (RUBY_VERSION >= '1.9' && encoding) ?
109
+ "w:#{encoding.to_s}" :
110
+ 'w'
111
+
112
+ File.open(filename, mode) do |f|
113
+ @ini.each do |section,hash|
114
+ f.puts "[#{section}]"
115
+ hash.each {|param,val| f.puts "#{param} #{@param} #{escape_value val}"}
116
+ f.puts
117
+ end
118
+ end
119
+
120
+ self
121
+ end
122
+ alias :save :write
123
+
124
+ # Public: Read the contents of the INI file from the file system and replace
125
+ # and set the state of this IniFile instance. If left unspecified the
126
+ # currently configured filename and encoding will be used when reading from
127
+ # the file system. Otherwise the filename and encoding can be specified in
128
+ # the options hash.
129
+ #
130
+ # opts - The default options Hash
131
+ # :filename - The filename as a String
132
+ # :encoding - The encoding as a String (Ruby 1.9)
133
+ #
134
+ # Returns this IniFile instance if the read was successful; nil is returned
135
+ # if the file could not be read.
136
+ #
137
+ def read( opts = {} )
138
+ filename = opts.fetch(:filename, @filename)
139
+ encoding = opts.fetch(:encoding, @encoding)
140
+ return unless File.file? filename
141
+
142
+ mode = (RUBY_VERSION >= '1.9' && encoding) ?
143
+ "r:#{encoding.to_s}" :
144
+ 'r'
145
+ fd = File.open(filename, mode)
146
+ @content = fd.read
147
+
148
+ parse!
149
+ self
150
+ ensure
151
+ fd.close if fd && !fd.closed?
152
+ end
153
+ alias :restore :read
154
+
155
+ # Returns this IniFile converted to a String.
156
+ #
157
+ def to_s
158
+ s = []
159
+ @ini.each do |section,hash|
160
+ s << "[#{section}]"
161
+ hash.each {|param,val| s << "#{param} #{@param} #{escape_value val}"}
162
+ s << ""
163
+ end
164
+ s.join("\n")
165
+ end
166
+
167
+ # Returns this IniFile converted to a Hash.
168
+ #
169
+ def to_h
170
+ @ini.dup
171
+ end
172
+
173
+ # Public: Creates a copy of this inifile with the entries from the
174
+ # other_inifile merged into the copy.
175
+ #
176
+ # other - The other IniFile.
177
+ #
178
+ # Returns a new IniFile.
179
+ #
180
+ def merge( other )
181
+ self.dup.merge!(other)
182
+ end
183
+
184
+ # Public: Merges other_inifile into this inifile, overwriting existing
185
+ # entries. Useful for having a system inifile with user over-ridable settings
186
+ # elsewhere.
187
+ #
188
+ # other - The other IniFile.
189
+ #
190
+ # Returns this IniFile.
191
+ #
192
+ def merge!( other )
193
+ my_keys = @ini.keys
194
+ other_keys =
195
+ case other
196
+ when IniFile; other.instance_variable_get(:@ini).keys
197
+ when Hash; other.keys
198
+ else raise "cannot merge contents from '#{other.class.name}'" end
199
+
200
+ (my_keys & other_keys).each do |key|
201
+ @ini[key].merge!(other[key])
202
+ end
203
+
204
+ (other_keys - my_keys).each do |key|
205
+ @ini[key] = other[key]
206
+ end
207
+
208
+ self
209
+ end
210
+
211
+ # Public: Yield each INI file section, parameter, and value in turn to the
212
+ # given block.
213
+ #
214
+ # block - The block that will be iterated by the each method. The block will
215
+ # be passed the current section and the parameter / value pair.
216
+ #
217
+ # Examples
218
+ #
219
+ # inifile.each do |section, parameter, value|
220
+ # puts "#{parameter} = #{value} [in section - #{section}]"
221
+ # end
222
+ #
223
+ # Returns this IniFile.
224
+ #
225
+ def each
226
+ return unless block_given?
227
+ @ini.each do |section,hash|
228
+ hash.each do |param,val|
229
+ yield section, param, val
230
+ end
231
+ end
232
+ self
233
+ end
234
+
235
+ # Public: Yield each section in turn to the given block.
236
+ #
237
+ # block - The block that will be iterated by the each method. The block will
238
+ # be passed the current section as a Hash.
239
+ #
240
+ # Examples
241
+ #
242
+ # inifile.each_section do |section|
243
+ # puts section.inspect
244
+ # end
245
+ #
246
+ # Returns this IniFile.
247
+ #
248
+ def each_section
249
+ return unless block_given?
250
+ @ini.each_key {|section| yield section}
251
+ self
252
+ end
253
+
254
+ # Public: Remove a section identified by name from the IniFile.
255
+ #
256
+ # section - The section name as a String.
257
+ #
258
+ # Returns the deleted section Hash.
259
+ #
260
+ def delete_section( section )
261
+ @ini.delete section.to_s
262
+ end
263
+
264
+ # Public: Get the section Hash by name. If the section does not exist, then
265
+ # it will be created.
266
+ #
267
+ # section - The section name as a String.
268
+ #
269
+ # Examples
270
+ #
271
+ # inifile['global']
272
+ # #=> global section Hash
273
+ #
274
+ # Returns the Hash of parameter/value pairs for this section.
275
+ #
276
+ def []( section )
277
+ return nil if section.nil?
278
+ @ini[section.to_s]
279
+ end
280
+
281
+ # Public: Set the section to a hash of parameter/value pairs.
282
+ #
283
+ # section - The section name as a String.
284
+ # value - The Hash of parameter/value pairs.
285
+ #
286
+ # Examples
287
+ #
288
+ # inifile['tenderloin'] = { 'gritty' => 'yes' }
289
+ # #=> { 'gritty' => 'yes' }
290
+ #
291
+ # Returns the value Hash.
292
+ #
293
+ def []=( section, value )
294
+ @ini[section.to_s] = value
295
+ end
296
+
297
+ # Public: Create a Hash containing only those INI file sections whose names
298
+ # match the given regular expression.
299
+ #
300
+ # regex - The Regexp used to match section names.
301
+ #
302
+ # Examples
303
+ #
304
+ # inifile.match(/^tree_/)
305
+ # #=> Hash of matching sections
306
+ #
307
+ # Return a Hash containing only those sections that match the given regular
308
+ # expression.
309
+ #
310
+ def match( regex )
311
+ @ini.dup.delete_if { |section, _| section !~ regex }
312
+ end
313
+
314
+ # Public: Check to see if the IniFile contains the section.
315
+ #
316
+ # section - The section name as a String.
317
+ #
318
+ # Returns true if the section exists in the IniFile.
319
+ #
320
+ def has_section?( section )
321
+ @ini.has_key? section.to_s
322
+ end
323
+
324
+ # Returns an Array of section names contained in this IniFile.
325
+ #
326
+ def sections
327
+ @ini.keys
328
+ end
329
+
330
+ # Public: Freeze the state of this IniFile object. Any attempts to change
331
+ # the object will raise an error.
332
+ #
333
+ # Returns this IniFile.
334
+ #
335
+ def freeze
336
+ super
337
+ @ini.each_value {|h| h.freeze}
338
+ @ini.freeze
339
+ self
340
+ end
341
+
342
+ # Public: Mark this IniFile as tainted -- this will traverse each section
343
+ # marking each as tainted.
344
+ #
345
+ # Returns this IniFile.
346
+ #
347
+ def taint
348
+ super
349
+ @ini.each_value {|h| h.taint}
350
+ @ini.taint
351
+ self
352
+ end
353
+
354
+ # Public: Produces a duplicate of this IniFile. The duplicate is independent
355
+ # of the original -- i.e. the duplicate can be modified without changing the
356
+ # original. The tainted state of the original is copied to the duplicate.
357
+ #
358
+ # Returns a new IniFile.
359
+ #
360
+ def dup
361
+ other = super
362
+ other.instance_variable_set(:@ini, Hash.new {|h,k| h[k] = Hash.new})
363
+ @ini.each_pair {|s,h| other[s].merge! h}
364
+ other.taint if self.tainted?
365
+ other
366
+ end
367
+
368
+ # Public: Produces a duplicate of this IniFile. The duplicate is independent
369
+ # of the original -- i.e. the duplicate can be modified without changing the
370
+ # original. The tainted state and the frozen state of the original is copied
371
+ # to the duplicate.
372
+ #
373
+ # Returns a new IniFile.
374
+ #
375
+ def clone
376
+ other = dup
377
+ other.freeze if self.frozen?
378
+ other
379
+ end
380
+
381
+ # Public: Compare this IniFile to some other IniFile. For two INI files to
382
+ # be equivalent, they must have the same sections with the same parameter /
383
+ # value pairs in each section.
384
+ #
385
+ # other - The other IniFile.
386
+ #
387
+ # Returns true if the INI files are equivalent and false if they differ.
388
+ #
389
+ def eql?( other )
390
+ return true if equal? other
391
+ return false unless other.instance_of? self.class
392
+ @ini == other.instance_variable_get(:@ini)
393
+ end
394
+ alias :== :eql?
395
+
396
+
397
+ private
398
+
399
+ # Parse the ini file contents. This will clear any values currently stored
400
+ # in the ini hash.
401
+ #
402
+ def parse!
403
+ return unless @content
404
+
405
+ string = ''
406
+ property = ''
407
+
408
+ @ini.clear
409
+ @_line = nil
410
+ @_section = nil
411
+
412
+ scanner = StringScanner.new(@content)
413
+ until scanner.eos?
414
+
415
+ # keep track of the current line for error messages
416
+ @_line = scanner.check(%r/\A.*$/) if scanner.bol?
417
+
418
+ # look for escaped special characters \# \" etc
419
+ if scanner.scan(%r/\\([\[\]#{@param}#{@comment}"])/)
420
+ string << scanner[1]
421
+
422
+ # look for quoted strings
423
+ elsif scanner.scan(%r/"/)
424
+ quote = scanner.scan_until(/(?:\A|[^\\])"/)
425
+ parse_error('Unmatched quote') if quote.nil?
426
+
427
+ quote.chomp!('"')
428
+ string << quote
429
+
430
+ # look for comments, empty strings, end of lines
431
+ elsif scanner.skip(%r/\A\s*(?:[#{@comment}].*)?$/)
432
+ string << scanner.getch unless scanner.eos?
433
+
434
+ process_property(property, string)
435
+
436
+ # look for the separator between property name and value
437
+ elsif scanner.scan(%r/#{@param}/)
438
+ if property.empty?
439
+ property = string.strip
440
+ string.slice!(0, string.length)
441
+ else
442
+ parse_error
443
+ end
444
+
445
+ # look for the start of a new section
446
+ elsif scanner.scan(%r/\A\s*\[([^\]]+)\]/)
447
+ @_section = @ini[scanner[1]]
448
+
449
+ # otherwise scan and store characters till we hit the start of some
450
+ # special section like a quote, newline, comment, etc.
451
+ else
452
+ tmp = scanner.scan_until(%r/([\n"#{@param}#{@comment}] | \z | \\[\[\]#{@param}#{@comment}"])/mx)
453
+ parse_error if tmp.nil?
454
+
455
+ len = scanner[1].length
456
+ tmp.slice!(tmp.length - len, len)
457
+
458
+ scanner.pos = scanner.pos - len
459
+ string << tmp
460
+ end
461
+ end
462
+
463
+ process_property(property, string)
464
+ end
465
+
466
+ # Store the property / value pair in the currently active section. This
467
+ # method checks for continuation of the value to the next line.
468
+ #
469
+ # property - The property name as a String.
470
+ # value - The property value as a String.
471
+ #
472
+ # Returns nil.
473
+ #
474
+ def process_property( property, value )
475
+ value.chomp!
476
+ return if property.empty? and value.empty?
477
+ return if value.sub!(%r/\\\s*\z/, '')
478
+
479
+ property.strip!
480
+ value.strip!
481
+
482
+ if property.empty?
483
+ current_section['values'] ||= []
484
+ current_section['values'] << value
485
+ else
486
+ current_section[property.dup] = unescape_value(value.dup)
487
+ end
488
+
489
+ property.slice!(0, property.length)
490
+ value.slice!(0, value.length)
491
+
492
+ nil
493
+ end
494
+
495
+ # Returns the current section Hash.
496
+ #
497
+ def current_section
498
+ @_section ||= @ini[@default]
499
+ end
500
+
501
+ # Raise a parse error using the given message and appending the current line
502
+ # being parsed.
503
+ #
504
+ # msg - The message String to use.
505
+ #
506
+ # Raises IniFile::Error
507
+ #
508
+ def parse_error( msg = 'Could not parse line' )
509
+ raise Error, "#{msg}: #{@_line.inspect}"
510
+ end
511
+
512
+ # Unescape special characters found in the value string. This will convert
513
+ # escaped null, tab, carriage return, newline, and backslash into their
514
+ # literal equivalents.
515
+ #
516
+ # value - The String value to unescape.
517
+ #
518
+ # Returns the unescaped value.
519
+ #
520
+ def unescape_value( value )
521
+ return value unless @escape
522
+
523
+ value = value.to_s
524
+ value.gsub!(%r/\\[0nrt\\]/) { |char|
525
+ case char
526
+ when '\0'; "\0"
527
+ when '\n'; "\n"
528
+ when '\r'; "\r"
529
+ when '\t'; "\t"
530
+ when '\\\\'; "\\"
531
+ end
532
+ }
533
+ value
534
+ end
535
+
536
+ # Escape special characters.
537
+ #
538
+ # value - The String value to escape.
539
+ #
540
+ # Returns the escaped value.
541
+ #
542
+ def escape_value( value )
543
+ return value unless @escape
544
+
545
+ value = value.to_s.dup
546
+ value.gsub!(%r/\\([0nrt])/, '\\\\\1')
547
+ value.gsub!(%r/\n/, '\n')
548
+ value.gsub!(%r/\r/, '\r')
549
+ value.gsub!(%r/\t/, '\t')
550
+ value.gsub!(%r/\0/, '\0')
551
+ value
552
+ end
553
+
554
+ end # IniFile
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: actionio-inifile
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.3
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tim Pease
9
+ - Wong Liang Zan
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-10-09 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bones-git
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ description: Parses ansible ini files
32
+ email:
33
+ - zan@liangzan.net
34
+ executables: []
35
+ extensions: []
36
+ extra_rdoc_files: []
37
+ files:
38
+ - lib/inifile.rb
39
+ - README.md
40
+ homepage: http://github.com/action-io/inifile
41
+ licenses: []
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ! '>='
56
+ - !ruby/object:Gem::Version
57
+ version: 1.3.6
58
+ requirements: []
59
+ rubyforge_project:
60
+ rubygems_version: 1.8.24
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Parses ansible ini files.
64
+ test_files: []