Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/simple+INI%2Dfiles+parser%2Fwriter?V=3
QUERY_STRINGV=3
CONTENT_TYPE
DOCUMENT_URI/revision/simple+INI-files+parser/writer
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.130.88
REMOTE_PORT33840
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.135.205.146
HTTP_CF_RAY8761b3d77ed6876c-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTclaudebot
HTTP_CF_CONNECTING_IP3.135.205.146
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: LINE -> END

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit {simple INI-files parser/writer} {The INI files so much used in Windows are plain text files with key/value pairs (like ''MainWindowGeometry=400x500+65+30'') and those pairs are usually grouped in sections, which are identified by a name surrounded by brackets (like ''[InterfaceOptions]''). This simplicity make the INI format specially useful for people who just want to add to their software the capability of saving/loading configurations, user preferences and things alike.

This pair of Tcl 8.5.x procedures can be used for parsing and creating simple INI-like files -- the "-like" here means that I made those procedures with no worries about canonical INI formatting, comments, etc., but this is just enough for saving and loading simple configuration files. The procedures use the ''dict'' data type introduced with Tcl 8.5, and simply by reading the source-code it is possible to know how to store data in a dict for saving it into a file, or how to use the data in a dict obtained from a INI-like file.

I am a newbie in Tcl programming --- you will surely notice it :) --- and, as said previously, this code is limited and ''not''intended for "real INIs" manipulation. Feel free to improve it, but please allow us all to know by updating the code below, and put here an explanation of what you have done...



===
 # 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
 }
----

See also:
   * [Config File Parser]
   * [Loading and Saving Application Configuration Files]
   * [One more inifile parser]
   * [Matthias Hoffmann - Tcl-Code-Snippets - Misc - Readprof]

----
[Category Package] from [tcllib] - [Category File]} regexp2} CALL {my render {simple INI-files parser/writer} {The INI files so much used in Windows are plain text files with key/value pairs (like ''MainWindowGeometry=400x500+65+30'') and those pairs are usually grouped in sections, which are identified by a name surrounded by brackets (like ''[InterfaceOptions]''). This simplicity make the INI format specially useful for people who just want to add to their software the capability of saving/loading configurations, user preferences and things alike.

This pair of Tcl 8.5.x procedures can be used for parsing and creating simple INI-like files -- the "-like" here means that I made those procedures with no worries about canonical INI formatting, comments, etc., but this is just enough for saving and loading simple configuration files. The procedures use the ''dict'' data type introduced with Tcl 8.5, and simply by reading the source-code it is possible to know how to store data in a dict for saving it into a file, or how to use the data in a dict obtained from a INI-like file.

I am a newbie in Tcl programming --- you will surely notice it :) --- and, as said previously, this code is limited and ''not''intended for "real INIs" manipulation. Feel free to improve it, but please allow us all to know by updating the code below, and put here an explanation of what you have done...



===
 # 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
 }
----

See also:
   * [Config File Parser]
   * [Loading and Saving Application Configuration Files]
   * [One more inifile parser]
   * [Matthias Hoffmann - Tcl-Code-Snippets - Misc - Readprof]

----
[Category Package] from [tcllib] - [Category File]}} CALL {my revision {simple INI-files parser/writer}} CALL {::oo::Obj3183186 process revision/simple+INI%2Dfiles+parser%2Fwriter} CALL {::oo::Obj3183184 process}

-errorcode

NONE

-errorinfo

Unknow state transition: LINE -> END
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4