Giter VIP home page Giter VIP logo

inifile's Introduction

inifile Build Status

This is a native Ruby package for reading and writing INI files.

Description

Although made popular by Windows, INI files can be used on any system thanks to their flexibility. They allow a program to store configuration data, which can then be easily parsed and changed. Two notable systems that use the INI format are Samba and Trac.

More information about INI files can be found on the Wikipedia Page.

Properties

The basic element contained in an INI file is the property. Every property has a name and a value, delimited by an equals sign =. The name appears to the left of the equals sign and the value to the right.

name=value

Sections

Section declarations start with [ and end with ] as in [section1] and [section2] shown in the example below. The section declaration marks the beginning of a section. All properties after the section declaration will be associated with that section.

Comments

All lines beginning with a semicolon ; or a number sign # are considered to be comments. Comment lines are ignored when parsing INI files.

Example File Format

A typical INI file might look like this:

[section1]
; some comment on section1
var1 = foo
var2 = doodle
var3 = multiline values \
are also possible

[section2]
# another comment
var1 = baz
var2 = shoodle

Implementation

The format of INI files is not well defined. Several assumptions are made by the inifile gem when parsing INI files. Most of these assumptions can be modified at, but the defaults are listed below.

Global Properties

If the INI file lacks any section declarations, or if there are properties decalared before the first section, then these properties will be placed into a default "global" section. The name of this section can be configured when creating an IniFile instance.

Duplicate Properties

Duplicate properties are allowed in a single section. The last property value set is the one that will be stored in the IniFile instance.

[section1]
var1 = foo
var2 = bar
var1 = poodle

The resulting value of var1 will be poodle.

Duplicate Sections

If you have more than one section with the same name then the sections will be merged. Duplicate properties between the two sections will follow the rules discussed above. Properties in the latter section will override properties in the earlier section.

Comments

The comment character can be either a semicolon ; or a number sign #. The comment character can appear anywhere on a line including at the end of a name/value pair declaration. If you wish to use a comment character in your value then you will need to either escape the character or put the value in double quotations.

[section1]
var1 = foo  # a comment
var2 = "foo # this is not a comment"
var3 = foo \# this is not a comment either

Multi-Line Values

Values can be continued onto multiple lines in two separate ways. Putting a slash at the end of a line will continue the value declaration to the next line. When parsing, the trailing slash will be consumed and will not appear in the resulting value. Comments can appear to the right of the trailing slash.

var1 = this is a \  # these comments will
multiline value     # be ignored by the parser

In the above example the resulting value for var1 will be this is a multiline value. If you want to preserve newline characters in the value then quotations should be used.

var2 = "this is a
multiline value"

The resulting value for var2 will be this is a\nmultiline value.

Escape Characters

Several escape characters are supported within the value for a property. These escape sequences will be applied to quoted and unquoted values alike. You can enable or disable escaping by setting the escape flag to true or false when creating an IniFile instance.

  • \0 -- null character
  • \n -- newline character
  • \r -- carriage return character
  • \t -- tab character
  • \\ -- backslash character

The backslash escape sequence is only needed if you want one of the escape sequences to appear literally in your value. For example:

property = this is not a tab \\t character

Value Type Casting

Some values will be type cast when parsed by the code. Those values are booleans, integers, floats, and empty strings are cast to nil.

  • "" --> nil
  • "42" --> 42
  • "3.14159" --> 3.14159
  • "true" --> true
  • "false" --> false
  • "normal string" --> "normal string"

Pretty basic stuff.

Install

gem install inifile

Testing

To run the tests:

$ rake

Examples

require 'inifile'
myini = IniFile.load('mytest.ini')
myini.each_section do |section|
  puts "I want #{myini[section]['somevar']} printed here!"
end

Contributing

Contributions are gladly welcome! For small modifications (fixing typos, improving documentation) you can use GitHub's in-browser editing capabilities to create a pull request. For larger modifications I would recommend forking the project, creating your patch, and then submitting a pull request.

Mr Bones is used to manage rake tasks and to install dependent files. To setup your environment ...

$ gem install bones
$ rake gem:install_dependencies

And always remember that rake -T will show you the list of available tasks.

License

MIT License Copyright (c) 2006 - 2014

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

inifile's People

Contributors

egeland avatar erebor avatar guilhem avatar hilli avatar mmacedo avatar smtlaissezfaire avatar trans avatar twp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

inifile's Issues

Quoted comment characters

I'm having trouble writing values correctly that contain comment characters (i.e. semicolon). Here's a gist that tries to illustrate the problem.

I think values that contain these characters maybe need to be quoted when writing?

backslashes are not properly parsed

Hi

I am using this gem to parse a file with backslashes, windows path, and it does not work.

I see you escape and unescape at various point, but I don't get why. I nooped both methods, and everything works as I expect.

As you parse line by line, there will most likely never be any \n and \r.
It would be very strange to find an \0, and it can be dismissed if found.
There's no reason to escape \t and .

What do you think of just getting rid of those two methods ?

Why do I get this error? Because of no HEREDOC support or something else?

Example portion of the input file from Perl utility:

[0]

; cse_abstract properties
section_name = actor
name = single_player
position = -251.26628112793, -19.6408023834229, -127.977920532227
direction = 0.00431653670966625, -1.39625442028046, -0.00068671052576974
s_flags = 0x29
version = 118
script_version = 7
spawn_id = 63

; cse_alife_object properties
game_vertex_id = 5
distance = 2.0999999
level_vertex_id = 8427
object_flags = 0xffffffbf
custom_data = <<END
[dont_spawn_character_supplies]

[spawn]
wpn_binoc
detector_simple
novice_outfit
device_torch
END

Getting IniFile::Error: Could not parse line: "wpn_binoc"

https://metacpan.org/pod/Config::IniFiles

Phone numbers

Hi,
I've found a typecast issue.
This is the example :

[test]
phoneNumber=+393333333333

The IniFile['test']['phoneNumber'] value become 393333333333 while it should be "+393333333333".

rubygems.org entry does not show "Source Code" link

Thanks for this gem.
The rubygems.org page does not list the github repo as "Homepage" nor as "Source Code" link. Later apparently can only be set via the rubygems.org page after a login. Would be nice if you specify it.

Add array syntax support

Would you be willing to add PHP like array syntax support for reading/generating ini files, such as:

[section]
val[]=1
val[]="stuf"
val[]="bla"

  def write( opts = {} )
    filename = opts.fetch(:filename, @filename)
    encoding = opts.fetch(:encoding, @encoding)
    mode = (RUBY_VERSION >= '1.9' && encoding) ?
         "w:#{encoding.to_s}" :
         'w'
    File.open(filename, mode) do |f|
      @ini.each do |section,hash|
        f.puts "[#{section}]"
        hash.each { |param,val| 
          if val.kind_of?(Array)
            val.each { |x| 
              f.puts "#{param}[] #{@param} #{escape_value x}"
            }
          else
            f.puts "#{param} #{@param} #{escape_value val}"
          end
        }
        f.puts
      end
    end
    self
  end

publish new release to rubygems?

Hi,
could you please publish a new release to rubygems? the last one is quite old and has no license attribute set. This is now fixed in the master branch.

Parameter division string not stored

If I have some text like this:

text/plain=gvim.desktop

I would expect the string dividing the parameter should be saved.

Instead I get this:

text/plain = gvim.desktop

Doesn't work in Ruby 1.8.7

adminuser@ubuntu-1204:$ ruby1.8 --version
ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]
adminuser@ubuntu-1204:
$ irb1.8
irb(main):001:0> require 'inifile'
SyntaxError: /usr/lib/ruby/vendor_ruby/inifile.rb:558: undefined (?...) sequence: /\A"(.*)(?<!)"\z/
from (irb):1:in `require'
from (irb):1
from :0

INI from String

The only functionality I see missing at this point is the ability to create an IniFile given string, rather than a file.

comments

comment is not stored when use .save() function.
i cos my comments

#!/usr/bin/env ruby
# encoding: utf-8
require 'inifile'
ini = IniFile.load('test.ini')
ini['section']['foo'] = 'baz'
ini.save

if test.ini have comment when save i lost it!

RegexpError on empty comment string

I want to completely disable comment parsing, but I get a RegexpError when trying to pass the empty string for the :comment option:

irb(main):004:0> a=IniFile::load("test.ini", :comment=>"")
RegexpError: empty char-class: /\A\s*(?:[].*)?$/
    from /home/foo/inifile/lib/inifile.rb:431:in `parse!'
    from /home/foo/inifile/lib/inifile.rb:148:in `read'
    from /home/foo/inifile/lib/inifile.rb:91:in `initialize'
    from /home/foo/inifile/lib/inifile.rb:35:in `new'
    from /home/foo/inifile/lib/inifile.rb:35:in `load'
    from (irb):4
    from /usr/bin/irb:12:in `<main>'

Could not parse line error if value contains "="

The following lines throw a could not parse error

VALUE=ends_with_equals=
AND_VALUE=ends_with_double_equals==
OR_VALUE=contains_=_anywhere

#26 seems to be the same issue but is is closed.

I cloned the repository with the intention of diagnosing the problem, but I am unable to run the tests:

Successfully installed bones-3.8.1
1 gem installed
➜  inifile git:(master) ✗ rake test                                                                                                                                                                        
rake aborted!
ArgumentError: invalid byte sequence in US-ASCII
/Users/ulottda/.rvm/gems/ruby-2.0.0-p481/gems/bones-3.8.1/lib/bones/helpers.rb:48:in `delete' 

Error while instaling

$ bundle install
Invalid gemspec in [/var/lib/gems/1.8/specifications/inifile-1.1.0.gemspec]: invalid date format in specification: "2012-02-28 00:00:00.000000000Z"
Invalid gemspec in [/var/lib/gems/1.8/specifications/inifile-1.1.0.gemspec]: invalid date format in specification: "2012-02-28 00:00:00.000000000Z"
Invalid gemspec in [/var/lib/gems/1.8/specifications/inifile-1.1.0.gemspec]: invalid date format in specification: "2012-02-28 00:00:00.000000000Z"

additional info

$ ruby -v
ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-linux]
$ uname -a
3.0.0-15-generic #26-Ubuntu SMP Fri Jan 20 15:59:53 UTC 2012 i686 i686 i386 GNU/Linux

Lack of newline at end of file causes error

If you have an ini file without a newline at the end of the file, it will fail to parse with a Could not parse line error. Example file:

[my_section]
my_property = And now I die.

[3.0.0] Doesn't work with lines that just have a single value

In a mysql ini file you can have this:

[mysqld]
sql-mode = no_auto_create_user
user = mysql
basedir = /usr/
datadir = /projects/data/mysql
socket = /var/lib/mysql/mysql.sock
pid_file = mysqld.pid
port = 3306
skip-name-resolve

The parser will choke on that last line. Is this not valid ini format?

SyntaxError @ line 558 in inifile.rb

Hi!

I'm having some trouble since commit 9ee7371. I'm using Capifony with Vagrant and receive the following error when i try to deploy.

/opt/vagrant_ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `gem_original_require': /opt/vagrant_ruby/lib/ruby/gems/1.8/gems/inifile-3.0.0/lib/inifile.rb:558: undefined (?...) sequence: /\A"(.*)(?<!\\)"\z/ (SyntaxError)
from /opt/vagrant_ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:36:in `require'
from /opt/vagrant_ruby/lib/ruby/gems/1.8/gems/capifony-2.8.0/lib/capifony_symfony2.rb:6

Looks like the following line is giving trouble:

self.value = $1 if value =~ %r/\A"(.*)(?<!\\)"\z/m

Is it a bug in inifile?

undefined method `length' for nil:NilClass

with inifile 1.1.0 works fine http://travis-ci.org/#!/stereobooster/jshintrb/jobs/2274486
but with inifile 2.0 http://travis-ci.org/#!/stereobooster/jshintrb/builds/2276434
produce error

D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/inifile-2.0.0/lib/inifile.rb:453:in `parse!'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/inifile-2.0.0/lib/inifile.rb:90:in `initialize'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/submodule-0.1.0/lib/submodule.rb:20:in `new'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/submodule-0.1.0/lib/submodule.rb:20:in `initialize'
D:/projects/jshintrb/Rakefile:8:in `new'
D:/projects/jshintrb/Rakefile:8:in `<top (required)>'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/lib/rake/rake_module.rb:25:in `load'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/lib/rake/rake_module.rb:25:in `load_rakefile'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/lib/rake/application.rb:501:in `raw_load_rakefile'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/lib/rake/application.rb:82:in `block in load_rakefile'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/lib/rake/application.rb:81:in `load_rakefile'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/lib/rake/application.rb:65:in `block in run'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/lib/rake/application.rb:133:in `standard_exception_handling'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/lib/rake/application.rb:63:in `run'
D:/tools/ruby-1.9.2-p290-i386-mingw32/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/bin/rake:33:in `<top (required)>'
D:/tools/ruby-1.9.2-p290-i386-mingw32/bin/rake:23:in `load'
D:/tools/ruby-1.9.2-p290-i386-mingw32/bin/rake:23:in `<main>'

ini vs. inifile

I noticed on Gemcutter there are two gems, ini and inifile. The ini gem appears to be a copy of inifile, but renamed. Tim, you are listed as an author on both. Do you control that gem too? Or is that under Rob Muhlestein's control? Considering they are essentially the same, but inifile is a little further along, it would be nice to see the two projects reunify --and IMHO under the more succinct 'ini' name.

Typecasting values

This isn't a bug but more of a feature request.

Would love to see a typecasting method to allow for values like 4.5, 6, true, false, etc

Here is a method that I use for simple typecasting:

def typecast(value)
  case value
    when /^\s*$/                                        then nil
    when /^-?(?:\d|[1-9]\d+)$/                          then Integer(value)
    when /^-?(?:\d|[1-9]\d+)(?:\.\d+)?(?:e[+-]?\d+)?$/i then Float(value)
    when /true/i                                        then true
    when /false/i                                       then false
    else                                                     value
  end
end

Be able to use value outside a section

Ini files can be quite bad and different.
Sometimes, values are alone before any section.
https://github.com/datafolklabs/ruby-parseconfig , for example, manage this case:

# Example Config
param1 = value1
param2 = value2

[group1]
group1_param1 = group1_value1
group1_param2 = group1_value2

[group2]
group2_param1 = group2_value1
group2_param2 = group2_value2

I wrote a commit some times ago: https://github.com/optiflows/inifile/commit/c037bff0edd1ff917d9b69fcdf69a8028d2a331f

But it's only a way to do. there may be other.

inifile raise an error while parsing a value containing the "="

As stated in the title here is the error:

/usr/lib/ruby/gems/1.9.1/gems/inifile-2.0.2/lib/inifile.rb:523:in `parse_error': Could not parse line: "Exec=/usr/lib/chromium/chromium --profile-directory=Default --app-id=ihmgiclibbndffejedjimfjmfoabpcke" (IniFile::Error)

Everything works fine except for this row which can't be parsed, i tried to find where there error is generated and seems that applying the comments as below in the parse! method it works:

...
     # look for the separator between property name and value
      elsif scanner.scan(%r/#{@param}/)

#         if property.empty?
          property = string.strip
          string.slice!(0, string.length)
#         else
#     p property
#           parse_error
#         end

      # look for the start of a new section
...

Error: file starts with a comment

I tried to load a file that starts with the below, but it threw an IniFile::Error for some reason.

# See the documentation on the wiki to learn how to edit this file.
#-------------------------------
[BULBASAUR]
Name = Bulbasaur
Types = GRASS,POISON
BaseStats = 45,49,49,45,65,65
GenderRatio = FemaleOneEighth
GrowthRate = Parabolic
BaseExp = 64

The error is:

C:/tools/ruby31/lib/ruby/gems/3.1.0/gems/inifile-3.0.0/lib/inifile.rb:578:in `error': Could not parse line: "# See the documentation on the wiki to learn how to edit this file." (IniFile::Error)
        from C:/tools/ruby31/lib/ruby/gems/3.1.0/gems/inifile-3.0.0/lib/inifile.rb:532:in `block in parse'
        from C:/tools/ruby31/lib/ruby/gems/3.1.0/gems/inifile-3.0.0/lib/inifile.rb:515:in `each_line'
        from C:/tools/ruby31/lib/ruby/gems/3.1.0/gems/inifile-3.0.0/lib/inifile.rb:515:in `parse'
        from C:/tools/ruby31/lib/ruby/gems/3.1.0/gems/inifile-3.0.0/lib/inifile.rb:400:in `parse'
        from C:/tools/ruby31/lib/ruby/gems/3.1.0/gems/inifile-3.0.0/lib/inifile.rb:128:in `block in read'
        from C:/tools/ruby31/lib/ruby/gems/3.1.0/gems/inifile-3.0.0/lib/inifile.rb:128:in `open'
        from C:/tools/ruby31/lib/ruby/gems/3.1.0/gems/inifile-3.0.0/lib/inifile.rb:128:in `read'
        from C:/tools/ruby31/lib/ruby/gems/3.1.0/gems/inifile-3.0.0/lib/inifile.rb:80:in `initialize'
        from C:/tools/ruby31/lib/ruby/gems/3.1.0/gems/inifile-3.0.0/lib/inifile.rb:31:in `new'
        from C:/tools/ruby31/lib/ruby/gems/3.1.0/gems/inifile-3.0.0/lib/inifile.rb:31:in `load'
        from spreadsheet_prepare.rb:5:in `<main>'

I'm trying to make a script, and it starts with the following:

require 'inifile'

pokemon = ARGV[0]
phash = IniFile.load("PBS/pokemon.txt")
phash.merge(IniFile.load("PBS/pokemon-forms.txt"))
mhash = IniFile.load("PBS/moves.txt")

Bad value parse in IniFile Gem

A carefully (or accidentally) crafted value can cause Inifile#load to become confused when it apparently incorrectly parses a string as a scientific notation value.

This script should print "2017.1_26_57e7669". Instead it prints "Infinity" (ruby 2.4.0 on CentOs 7)

#!/usr/bin/env ruby

require 'inifile'

inifile = IniFile.new(:filename => "file.ini")
inifile['global'] = { "buggystuff" => "2017.1_26_57e7669" }
inifile.write

inifile2 = IniFile.load("file.ini")
global = inifile2["global"]
p global["buggystuff"]

Quoting problems.

My picasa.ini has entries like:

[2014-03-09_18-31-01--VID_20140309_183101.mp4]
caption=More F "reading" out memorized books.
backuphash=35308

2.0.2 was fine with this. 3.0.0 considers it "unbalanced quotes", and barfs. I don't think that's what you had in mind when you added the quoting mechanism?

Seems to me like it should enforce quoting IFF the value starts with a ". Better still, have an option to set the quote marker and/or turn it off.

for loop in .ini file

Hi everybody,
Is it possible to define a for loop in a .ini file?
For example we have for loop in C or Python,...
Can we define such loops in .ini file?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.