how to parse INI files ?

D

dreamcatcher

I want my program to parse INI files, only have little clue of how to do
that, though, hope you guys might shed some light on this, thanx.



for example:



[configuration]

admin=dreamcatcher



[variables]

var1=100

var2="string literal"

var3=0x4234

var4=1010101010101



[adaptor]

vga=Super VGA
 
R

Richard Heathfield

dreamcatcher said:
I want my program to parse INI files, only have little clue of how to do
that, though, hope you guys might shed some light on this, thanx.
for example:
[configuration]
admin=dreamcatcher
[variables]
var1=100
var2="string literal"
var3=0x4234
var4=1010101010101
[adaptor]
vga=Super VGA

(Whitespace stripped mercilessly)

Okay, as you can see, there's a sort of grammar here. Let's see how I do:

INI-file:
section
section INI-file

section:
section-title var-list

section-title:
'[' section-identifier ']'

section-identifier:
a sequence of characters not including ']'

var-list:
var-value-pair
var-value-pair var-list

var-value-pair:
variable '=' value

variable:
a sequence of characters not including '='

value:
a sequence of characters terminating in a newline character



I think I got that right. Implement that language, and you're laughing.
 
T

Tom St Denis

dreamcatcher said:
I want my program to parse INI files, only have little clue of how to do
that, though, hope you guys might shed some light on this, thanx.

You could trivially write a hand-written parser for these. You just need to
actually do your homework.

Tom
 
M

Morris Dovey

dreamcatcher said:
I want my program to parse INI files, only have little clue of
how to do that, though, hope you guys might shed some light on
this, thanx.

for example:

[configuration]
admin=dreamcatcher

[variables]
var1=100
var2="string literal"
var3=0x4234
var4=1010101010101

[adaptor]
vga=Super VGA

Dreamcatcher...

There are three aspects to this problem:

1. Input and parse each line
2. Save the information in some usable form
3. Access the information as needed

(1) isn't too difficult
(2) is easily handled by building a linked list of sections;
and by attaching a list of key/value structures to each
section.
(3) is most easily handled by writing a set of functions
like:

find_section()
next_section()
find_key()
next_key()

I found it helpful to provide a [Global] section (the name isn't
particularly significant) under which any key=value entries
preceeding the first named section are linked. If there are no
such entries, then I don't provide the [Global] section element.

You may also find it helpful to provide for comment lines and/or
end of line comments to make the .ini file more readable and
maintainable.

I also added the ability to have lines of text in the file (in
addition to key=value lines); and am playing with adding CSV data
lines.
 
T

Tristan Miller

Greetings.

Okay, as you can see, there's a sort of grammar here. Let's see how I do:
[snip]

I think I got that right. Implement that language, and you're laughing.

Though the language is simple enough as it is, lex and yacc (or flex and
bison) would speed development here. In just a few minutes you'll get a
shiny new INI file parser written specially for you in ANSI C.
 
M

Michel Bardiaux

Morris said:
dreamcatcher said:
I want my program to parse INI files, only have little clue of
how to do that, though, hope you guys might shed some light on
this, thanx.

for example:

[configuration]
admin=dreamcatcher

[variables]
var1=100
var2="string literal"
var3=0x4234
var4=1010101010101

[adaptor]
vga=Super VGA


Dreamcatcher...

There are three aspects to this problem:

1. Input and parse each line
2. Save the information in some usable form
3. Access the information as needed

(1) isn't too difficult

ACtually, there are many pitfalls:

(1) What of duplicate sections?

(2) What of duplicate keys?

(3) What of space before/after, the key/the value?

(4) Is order significant? Should it be maintained?

(5) What of KVPs outside a section? A proposal was made by Morris
(below), but it is not the only possible one, one could ignore them with
or without warning.

(6) What of lines not conforming to K=V? Here again a proposal is made
by Morris, but is it the best? Maximal compatibility with MS-Windows
could be a design goal.
(2) is easily handled by building a linked list of sections;
and by attaching a list of key/value structures to each
section.

I would rather use B-tree of sections, with B-tree of key/value pairs,
plus hased keys for fast comparisons.
(3) is most easily handled by writing a set of functions
like:

find_section()
next_section()
find_key()
next_key()

A stateful API. Yuck.
I found it helpful to provide a [Global] section (the name isn't
particularly significant) under which any key=value entries preceeding
the first named section are linked. If there are no such entries, then I
don't provide the [Global] section element.

You may also find it helpful to provide for comment lines and/or end of
line comments to make the .ini file more readable and maintainable.

I also added the ability to have lines of text in the file (in addition
to key=value lines); and am playing with adding CSV data lines.
 
M

Morris Dovey

Michel said:
Morris Dovey wrote:
ACtually, there are many pitfalls:

(1) What of duplicate sections?

I treated the second (and subsequent) duplicate section as an
(intended) continuation of the first.
(2) What of duplicate keys?

I allowed duplicate keys; and if the value associated with the
duplicate didn't duplicate an existing entry's in the current
section, created a new KVP entry for the current section. If the
application didn't like duplicate keys, /it/ could complain,
abort, etc.
(3) What of space before/after, the key/the value?

I strip leading and trailing spaces from section names, keys, and
values. When multiple spaces are found within section names and
keys, they are reduced to single spaces. Multiple spaces within
values are retained.
(4) Is order significant? Should it be maintained?

I maintained the order of /first instance/ of sections and KVPs
within each section. KVPs and text entries were kept in separate
lists. (BTW, this was my rationale for using linked lists.)
(5) What of KVPs outside a section? A proposal was made by Morris
(below), but it is not the only possible one, one could ignore them with
or without warning.

It struck me as perilous to silently discard configuration data;
and I preferred to have the application do any complaining. This
was my rationale for the "ghost" [Global] section.
(6) What of lines not conforming to K=V? Here again a proposal is made
by Morris, but is it the best? Maximal compatibility with MS-Windows
could be a design goal.

Well, I'd actually /wanted/ section-specific (multi-line) text,
so that's what I built in. Given that it supported a requirement
rather exactly, it /was/ the best solution. (But YMMV. :cool:

Given that I'm pretty much a POSIX bigot, I felt completely free
to improve on MS-anything (and they make it /so/ easy to do!)
I would rather use B-tree of sections, with B-tree of key/value pairs,
plus hased keys for fast comparisons.

Ok by me. My .ini files were relatively small (under 24k); and I
wasn't too worried about one-time initialization overhead. Again,
YMMV.
A stateful API. Yuck.

Stateful, yes. Yuck? Beauty is in the eye of the beholder. The
code was quick, simple, and reliable. All told, the package took
less than two hours to design, code, and debug -- and I was on to
the actual application code. Production of a reliable major
application delivered considerably under budget and much ahead of
schedule made a very happy client, who found it beautiful! (BTW,
they particularly liked the extreme flexibility that the various
configuration files provided.)
 
M

Michel Bardiaux

Morris said:
Michel said:
Morris Dovey wrote:


ACtually, there are many pitfalls:

(1) What of duplicate sections?


I treated the second (and subsequent) duplicate section as an (intended)
continuation of the first.
(2) What of duplicate keys?


I allowed duplicate keys; and if the value associated with the duplicate
didn't duplicate an existing entry's in the current section, created a
new KVP entry for the current section. If the application didn't like
duplicate keys, /it/ could complain, abort, etc.
(3) What of space before/after, the key/the value?


I strip leading and trailing spaces from section names, keys, and
values. When multiple spaces are found within section names and keys,
they are reduced to single spaces. Multiple spaces within values are
retained.
(4) Is order significant? Should it be maintained?


I maintained the order of /first instance/ of sections and KVPs within
each section. KVPs and text entries were kept in separate lists. (BTW,
this was my rationale for using linked lists.)
(5) What of KVPs outside a section? A proposal was made by Morris
(below), but it is not the only possible one, one could ignore them
with or without warning.


It struck me as perilous to silently discard configuration data; and I
preferred to have the application do any complaining. This was my
rationale for the "ghost" [Global] section.
(6) What of lines not conforming to K=V? Here again a proposal is made
by Morris, but is it the best? Maximal compatibility with MS-Windows
could be a design goal.


Well, I'd actually /wanted/ section-specific (multi-line) text, so
that's what I built in. Given that it supported a requirement rather
exactly, it /was/ the best solution. (But YMMV. :cool:

Given that I'm pretty much a POSIX bigot, I felt completely free to
improve on MS-anything (and they make it /so/ easy to do!)

I was taking exception to the idea that parsing was "relatively easy"; I
see you've pretty much covered all the bases. Even though I disagree
with most of your design decisions - I disallow duplicate sections,
duplicate keys, out-of-section keys, and order is neither relevant nor
maintained; and MSW compatibility *was* an important point, because we
do have customers who want MSW applications. The important issue is not
what choices are made, but that they are made at all and fully documented.
Ok by me. My .ini files were relatively small (under 24k); and I wasn't
too worried about one-time initialization overhead. Again, YMMV.

We have strongly optimized access to the .INI; then it becomes practical
to look them up when needed, rather than writing all the data structures
needed to keep the information in-core.
Stateful, yes. Yuck? Beauty is in the eye of the beholder. The code was
quick, simple, and reliable.

A POSIX bigot using an API modelled on FindFirst/FindNext? :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top