Ruby gem for parsing .cfg files

Overview

PyPi module N/A
git repository https://bitbucket.org/arrizza-public/rb-cfg-parser
git command git clone git@bitbucket.org:arrizza-public/rb-cfg-parser.git
Verification Report https://arrizza.com/web-ver/rb-cfg-parser-report.html
Version Info
OS Language #Runs Last Run Cov%
Ubuntu 24.04 noble Ruby 3.2.3 362 2025-03-13 99.07

Summary

This Ruby gem parses a .cfg file based on how python's configparser module works.

The need for this came from a "cross-platform utilities" (xplat_utils) repo that I use to maintain the many projects for my website. It works on Python, Ruby, C/C++, Android for now.

Having a common .cfg format is ideal in that scenario.

  • sample run
./doit

Typical output:

  >> cfg:
  >>    version:  0.0.2
  >>    mod_name: rb-cfg-parser
  >>    desc:     ruby gem to parse and load .cfg files
  >>    slug:     {mod_name}
  >>
     doit: run_it rc=0

How to use

See sample/main.rb for an example of how to run it:

parser = RbCfgParser.new
cfg    = parser.parse_file('xplat.cfg')
puts('  >> cfg:')
puts("  >>    version:  #{cfg['xplat']['version']}")
puts("  >>    mod_name: #{cfg['xplat']['mod_name']}")
puts("  >>    desc:     #{cfg['xplat']['desc']}")
puts('  >>')

See ut/ut_*.rb for examples of all the possible formats it recognizes.

parsing

A cfg file can be parsed or a string can be parsed:

parser = RbCfgParser.new
cfg = parser.parse_file('xplat.cfg')
cfg = parser.parse_str(lines)

The content returned is a hash. The key is the section_name and the variables within that section are held as a hash.

[section_name]  
variable = value
# cfg['section_name']['variable'] == 'value'

comments

Line comments are allowed. Lines starting with ';' or '#' are considered comments

; comment 1
# comment 2

Trailing comments are not recommended. They may work okay but may also cause problems:

[sect1]       # comment 1    <== will be ignored
vrbl1 = val1
        val2  ; comment2     <== will be part of the values in vrbl1

sections

In the cfg, a section names a group of variables.

Sections are wrapped in square brackets:

[section_a]
[section b]
[  section c  ]   # leading/trailing spaces are stripped, the section name is "section c" 

There is an :unnamed section automatically declared:

vrbl1 = val1     # held in section :unnamed , cfg[:unname]['vrbl1'] == 'val1'
[sect1]
vrbl2 = val2

variables and values

Variables may have one value. The value may be single- or double-quoted

# these all hold the same value 'val1'
vrbl1 = val1
vrbl1 = 'val1'  
vrbl1 = "val1"

Variables may have no/empty value:

# these all hold the same value ''
vrbl1 = 
vrbl1 = ''  
vrbl1 = ""

Variables may have multiple values:

# these all hold the same array ['val1', 'val2', 'val3']
vrbl1 = val1 val2 val3
vrbl1 = 'val1' 'val2' 'val3'  
vrbl1 = "val1" "val2" "val3"

Warning: there is currently an issue is inconsistent quoting is done:

# these will return the incorrect array ['val1', 'val3']
vrbl1 = 'val1' val2 'val3'  
vrbl1 = 'val1' "val2" 'val3'
vrbl1 = "val1" 'val2' "val3"

Variables may be on multiple lines:

# this returns an array ['val1', 'val2', 'val3']
vrbl1 = 'val1'
        'val2'
        'val3'

Note mixed quoted are okay, but recommended since converting them to a single line will cause errors

# this returns an array ['val1', 'val2', 'val3']
vrbl1 = 'val1'
        val2
        "val3"

- John Arrizza