본문으로 바로가기

출처: http://wiki.tcl.tk/22717

 

외국의 어느 개발자가 작성한 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
 }