외국의 어느 개발자가 작성한 ini 파서입니다. 의외로 dict를 이용한 기발한 생각입니다. dict는 8.5에 기본으로 포함되어 있습니다. 이하의 버전은 패키지를 설치하세요.
# ini2dict
# Parses the content of a INI-like file into a dict, where 1st key is the
# section name, 2nd key is a key and 3rd item is the value for the key.
# ARGUMENTS: 'filepath' is the absolute path of the file to be parsed;
# 'separator' is the separator between keys and values.
# RETURNS: a dict variable; or "" if an error happens.
proc ini2dict { filepath {separator =}} {
if {$filepath ==""} {
return ""
}
if {![file exists $filepath] || [catch { set fh [open $filepath r] } ] } {
return ""
}
while {![chan eof $fh]} {
gets $fh line
if { [string length $line] < 2 } {
continue
}
if { [regexp {^[[:blank:]]*\[{1}.*\]{1}} $line sect] } {
set sect [string range $sect 1 end-1]
continue
}
set seppoint [string first $separator $line]
if { [string length $sect] && $seppoint > 1 } {
set key [string range $line 0 [expr { $seppoint - 1 }]]
set value [string range $line [expr { $seppoint + 1}] end ]
dict set dic $sect $key $value
}
}
close $fh
return $dic
}
# dict2ini
# Writes the content of a dict in a INI-like file. The dict must be
# configured as that: 1st key is the section (which will be written to file
# between square brackets); 2nd key is the key itself; 3rd level is the value
# for the key.
# ARGUMENTS: 'filepath' is the absolute pathname for a file (if existent, will
# be overwritten); 'dic' is a dict variable; 'separator' is the character which
# will be placed right after each key.
# RETURN: 1 if the file was successfully written, 0 otherwise.
proc dict2ini { filepath dic {separator =}} {
if { $filepath == "" } {
return 0
}
if { [catch { set fh [open $filepath w] }] } {
# Error happened!
return 0
}
dict for { sect keyval } $dic {
puts $fh "\[$sect\]"
dict for { key val } $keyval {
puts $fh "$key$separator$val"
}
}
close $fh
return 1
}