1 # this line is needed for our install script, to keep up with different versions
\r
6 # INIParse v1.4 (C)2000
\r
13 # iniparse:openfile <filename> ?RDONLY?
\r
15 # Reads an ini file into memory, for later access (such as read or write),
\r
16 # and return an id which can be later used for writing/reading data, and
\r
17 # flushing/closing file.
\r
20 # - It doesn't leave the file open, just reads into memory, and returns an id.
\r
21 # - If RDONLY is specified (case-sensetive), then calls to writeini will work
\r
22 # only in memory, and changes won't be saved with iniparse:flush, nor
\r
23 # iniparse:closefile.
\r
28 # iniparse:flushfile <fileId>
\r
30 # Writes an ini file in memory into its file, without removing data from
\r
36 # iniparse:closefile <fileId>
\r
38 # Flushes an ini file in memory into its file, and then removes data from
\r
44 # readini <fileId> [ [<keyname>] [<itemname>] ]
\r
45 # Reads <itemname> under <keyname> from <fileId>. If it cannot find
\r
46 # file, <itemname>, or <keyname>, returns an empty string.
\r
47 # If itemname is absent, returns list of all items under keyname.
\r
50 # - This procedure doesn't read directly from the file, but from the
\r
51 # memory-version of the file. If directly the file (not memory version) is
\r
52 # modified after the call to iniparse:openfile, this procedure will not
\r
53 # see the changes in the file, but only changes in memory-version.
\r
55 # See: writeini iniparse:openfile
\r
60 # writeini <fileId> <keyname> <itemname> <itemvalue>
\r
61 # Writes/modifies <itemname> under <keyname> in <fileId>. If cannot
\r
62 # find <itemname>, or <keyname>, creates a new one.
\r
65 # - This procedure doesn't write directly to the file, but to the
\r
66 # memory-version of the file. If directly the file (not memory version) is
\r
67 # modified after the call to iniparse:openfile, this procedure will not
\r
68 # see the changes in the file, but only changes in memory-version.
\r
70 # See: readini iniparse:openfile
\r
75 # iniparse:removeitem <fileId> <keyname> <itemname>
\r
76 # Removes <itemname> under <keyname> in <fileId>.
\r
79 # - This procedure doesn't write directly to the file, but to the
\r
80 # memory-version of the file. If directly the file (not memory version) is
\r
81 # modified after the call to iniparse:openfile, this procedure will not
\r
82 # see the changes in the file, but only changes in memory-version.
\r
84 # See: readini iniparse:openfile
\r
89 # iniparse:removekey <fileId> <keyname>
\r
90 # Removes <keyname> in <fileId>.
\r
93 # - This procedure doesn't write directly to the file, but to the
\r
94 # memory-version of the file. If directly the file (not memory version) is
\r
95 # modified after the call to iniparse:openfile, this procedure will not
\r
96 # see the changes in the file, but only changes in memory-version.
\r
98 # See: readini iniparse:openfile
\r
103 # iniparse:renameitem <fileId> <keyname> <itemName> <newItemName>
\r
104 # Renames <itemName> under <keyname> in <fileId> to <newItemName>.
\r
107 # - This procedure doesn't write directly to the file, but to the
\r
108 # memory-version of the file. If directly the file (not memory version) is
\r
109 # modified after the call to iniparse:openfile, this procedure will not
\r
110 # see the changes in the file, but only changes in memory-version.
\r
112 # See: readini iniparse:openfile
\r
117 # iniparse:renamekey <fileId> <keyname> <newKeyName>
\r
118 # Renames <keyname> in <fileId> to <newKeyName>.
\r
121 # - This procedure doesn't write directly to the file, but to the
\r
122 # memory-version of the file. If directly the file (not memory version) is
\r
123 # modified after the call to iniparse:openfile, this procedure will not
\r
124 # see the changes in the file, but only changes in memory-version.
\r
126 # See: readini iniparse:openfile
\r
128 #############################################################################
\r
130 package provide iniparse 1.4
\r
132 set iniparse(freeid) 0
\r
133 set iniparse(idlist) {}
\r
134 #$iniparse($id,fname) - filename
\r
135 #$iniparse($id,data) - each line in file are read into an item in this list
\r
136 #$iniparse($id,flags) - this is a list containing these flags:
\r
137 # RDONLY : If this flag is set, iniparse:flush will
\r
138 # not write anything over file, but still
\r
139 # writeini will work (only in memory)
\r
142 proc rtrimleft {bigstr srcstr} {
\r
143 set istring1 [string length $srcstr]
\r
144 if {$srcstr == [string range $bigstr 0 [expr $istring1-1]]} {
\r
145 return [string range $bigstr $istring1 end]
\r
149 proc chrchk {arg} {
\r
150 if {[string index $arg 0] == "\[" && [string index $arg end] == "\]"} {
\r
158 # iniparse:openfile <filename> ?RDONLY?
\r
160 # Reads an ini file into memory, for later access (such as read or write),
\r
161 # and return an id which can be later used for writing/reading data, and
\r
162 # flushing/closing file.
\r
165 # - It doesn't leave the file open, just reads into memory, and returns an id.
\r
166 # - If RDONLY is specified (case-sensetive), then calls to writeini will work
\r
167 # only in memory, and changes won't be saved with iniparse:flush, nor
\r
168 # iniparse:closefile.
\r
170 proc iniparse:openfile {file args} {
\r
173 set fileId [open $file {RDONLY CREAT}]
\r
176 while {![eof $fileId]} {
\r
177 set input [gets $fileId]
\r
178 if {[string match {\[*\]} $input]} {lappend filedata "" $input} \
\r
179 elseif {[string match {*=*} $input] || \
\r
180 [string match {#*} $input]} {lappend filedata $input}
\r
185 set id $iniparse(freeid)
\r
186 incr iniparse(freeid)
\r
188 set iniparse($id,fname) $file
\r
189 set iniparse($id,data) $filedata
\r
190 set iniparse($id,flags) $args
\r
191 lappend iniparse(idlist) $id
\r
198 # iniparse:flushfile <fileId>
\r
200 # Writes an ini file in memory into its file, without removing data from
\r
203 proc iniparse:flushfile {id} {
\r
206 if {[lsearch $iniparse(idlist) $id] == -1} return ;# No such Id
\r
208 if {[lsearch $iniparse($id,flags) RDONLY] != -1} return ;# ReadOnly-Flag
\r
210 set fileId [open $iniparse($id,fname) {WRONLY CREAT TRUNC}]
\r
212 foreach line $iniparse($id,data) {
\r
213 if {[string match {\[*\]} $line]} {puts $fileId "\n$line"} \
\r
214 elseif {[string match {*=*} $line] || \
\r
215 [string match {#*} $line]} {puts $fileId $line}
\r
219 set iniparse($id,flags) [lreplace $iniparse($id,flags) [set idx [lsearch $iniparse($id,flags) CHANGED]] $idx]
\r
224 # iniparse:closefile <fileId>
\r
226 # Flushes an ini file in memory into its file, and then removes data from
\r
229 proc iniparse:closefile {id} {
\r
232 if {[lsearch $iniparse(idlist) $id] == -1} return ;# No such Id
\r
234 iniparse:flushfile $id
\r
235 unset iniparse($id,fname)
\r
236 unset iniparse($id,data)
\r
237 unset iniparse($id,flags)
\r
238 set iniparse(idlist) [lreplace $iniparse(idlist) [set idx [lsearch $iniparse(idlist) $id]] $idx]
\r
243 # readini <fileId> [ [<keyname>] [<itemname>] ]
\r
244 # Reads <itemname> under <keyname> from <fileId>. If it cannot find
\r
245 # file, <itemname>, or <keyname>, returns an empty string.
\r
246 # If itemname is absent, returns list of all items under keyname.
\r
249 # - This procedure doesn't read directly from the file, but from the
\r
250 # memory-version of the file. If directly the file (not memory version) is
\r
251 # modified after the call to iniparse:openfile, this procedure will not
\r
252 # see the changes in the file, but only changes in memory-version.
\r
254 # See: writeini iniparse:openfile
\r
256 proc readini {id args} {
\r
258 set keyfound 0 ; set itemfound 0
\r
259 set key [lindex $args 0]
\r
260 set item [lindex $args 1]
\r
261 set itemlength [string length $item]
\r
266 if {[lsearch $iniparse(idlist) $id] == -1} {return ""} ;# No such Id
\r
269 set lidx 0 ;# line index
\r
270 set llen [llength $iniparse($id,data)]
\r
271 set data $iniparse($id,data) ;# for fast access
\r
273 while {$lidx < $llen} {
\r
274 set input [lindex $data $lidx]
\r
275 if {[chrchk $input]} {
\r
276 if {$input == "\[$key\]"} {
\r
277 # looks like we found our key..
\r
278 set keyfound 1 ; break
\r
281 regsub -all {\[|\]} $input {} baccum
\r
282 lappend kaccum $baccum
\r
289 if {$keyfound == 1} {
\r
290 while {$lidx < $llen} {
\r
291 set input [lindex $data $lidx]
\r
292 if {![chrchk $input]} {
\r
293 if {[string range $input 0 $itemlength]==$item} {
\r
294 set fValue [rtrimleft $input $item]
\r
298 set itemNdx [string first "=" $input]
\r
299 if {$itemNdx != -1} {
\r
300 lappend iaccum [string range $input 0 [expr $itemNdx - 1]]
\r
303 } elseif {[chrchk $input]} {
\r
304 # oops, we hit the next key.. looks like that item isnt here.
\r
309 } elseif {$keyfound == 0} {
\r
310 if {[llength $args] == 0} {
\r
313 return "" ;# no key exists called $key
\r
316 if {$itemfound == 1} {
\r
318 } elseif {[llength $args] != 2} {
\r
321 return "" ;# no item exists called "[string range $item 0 [expr [string length $item] - 2]]"
\r
327 # writeini <fileId> <keyname> <itemname> <itemvalue>
\r
328 # Writes/modifies <itemname> under <keyname> in <fileId>. If cannot
\r
329 # find <itemname>, or <keyname>, creates a new one.
\r
332 # - This procedure doesn't write directly to the file, but to the
\r
333 # memory-version of the file. If directly the file (not memory version) is
\r
334 # modified after the call to iniparse:openfile, this procedure will not
\r
335 # see the changes in the file, but only changes in memory-version.
\r
337 # See: readini iniparse:openfile
\r
339 proc writeini {id key item value} {
\r
344 set itemlength [string length $item]
\r
347 if {[lsearch $iniparse(idlist) $id] == -1} return ;# No such Id
\r
350 set lidx 0 ;# line index
\r
351 set llen [llength $iniparse($id,data)]
\r
352 set fileline $iniparse($id,data)
\r
355 foreach line $fileline {
\r
356 if {(!$keyfound)} { ;# We will search for the key.
\r
357 if {$line=="\[$key\]"} {
\r
358 lappend data "" $line
\r
363 if {($keyfound) && (!$itemfound) && [chrchk $line]} { ;# We hit the next key!
\r
364 lappend data "$item$value"
\r
365 lappend data "" $line
\r
369 if {($keyfound) && (!$itemfound)} { ;# We will search for the item
\r
370 if {[string range $line 0 $itemlength]==$item} {
\r
371 lappend data "$item$value"
\r
376 # Because it doesn't match anything above, we print the line to file
\r
377 if {[chrchk $line]} {lappend data "" $line} \
\r
378 else {lappend data $line}
\r
381 if {(!$keyfound) && (!$itemfound)} {
\r
382 lappend data "" "\[$key\]"
\r
383 lappend data "$item$value"
\r
384 } elseif {$keyfound && (!$itemfound)} {
\r
385 lappend data "$item$value"
\r
388 set iniparse($id,data) $data
\r
393 # iniparse:removeitem <fileId> <keyname> <itemname>
\r
394 # Removes <itemname> under <keyname> in <fileId>.
\r
397 # - This procedure doesn't write directly to the file, but to the
\r
398 # memory-version of the file. If directly the file (not memory version) is
\r
399 # modified after the call to iniparse:openfile, this procedure will not
\r
400 # see the changes in the file, but only changes in memory-version.
\r
402 # See: readini iniparse:openfile
\r
404 proc iniparse:removeitem {id key item} {
\r
409 set itemlength [string length $item]
\r
412 if {[lsearch $iniparse(idlist) $id] == -1} return ;# No such Id
\r
414 set fileline $iniparse($id,data)
\r
417 foreach line $fileline {
\r
418 if {(!$keyfound)} { ;# We will search for the key.
\r
419 if {$line=="\[$key\]"} {
\r
420 lappend data "" $line
\r
423 } else {lappend data $line; continue}
\r
425 if {($keyfound) && (!$itemfound) && [chrchk $line]} { ;# We hit the next key!
\r
426 lappend data "" $line
\r
430 if {($keyfound) && (!$itemfound)} { ;# We will search for the item
\r
431 if {[string range $line 0 $itemlength]==$item} {
\r
433 continue ;# We don't print the line to file
\r
434 } else {lappend data $line; continue}
\r
436 # Because it doesn't match anything above, we print the line to file
\r
437 if {[chrchk $line]} {lappend data "" $line} \
\r
438 else {lappend data $line}
\r
441 set iniparse($id,data) $data
\r
446 # iniparse:removekey <fileId> <keyname>
\r
447 # Removes <keyname> in <fileId>.
\r
450 # - This procedure doesn't write directly to the file, but to the
\r
451 # memory-version of the file. If directly the file (not memory version) is
\r
452 # modified after the call to iniparse:openfile, this procedure will not
\r
453 # see the changes in the file, but only changes in memory-version.
\r
455 # See: readini iniparse:openfile
\r
457 proc iniparse:removekey {id key} {
\r
463 if {[lsearch $iniparse(idlist) $id] == -1} return ;# No such Id
\r
465 set fileline $iniparse($id,data)
\r
468 foreach line $fileline {
\r
469 if {(!$keyfound)} { ;# We will search for the key.
\r
470 if {$line=="\[$key\]"} {
\r
475 if {($keyfound) && (!$keyfinished) && (![chrchk $line])} { ;# We are waiting for the next key
\r
478 if {($keyfound) && (!$keyfinished) && ([chrchk $line])} { ;# We are hit the next key!
\r
479 lappend data "" $line
\r
483 # Because it doesn't match anything above, we print the line to file
\r
484 if {[chrchk $line]} {lappend data "" $line} \
\r
485 else {lappend data $line}
\r
488 set iniparse($id,data) $data
\r
493 # iniparse:renameitem <fileId> <keyname> <itemName> <newItemName>
\r
494 # Renames <itemName> under <keyname> in <fileId> to <newItemName>.
\r
497 # - This procedure doesn't write directly to the file, but to the
\r
498 # memory-version of the file. If directly the file (not memory version) is
\r
499 # modified after the call to iniparse:openfile, this procedure will not
\r
500 # see the changes in the file, but only changes in memory-version.
\r
502 # See: readini iniparse:openfile
\r
504 proc iniparse:renameitem {id key olditem newitem} {
\r
505 writeini $id $key $newitem [readini $id $key $olditem]
\r
506 iniparse:removeitem $id $key $olditem
\r
511 # iniparse:renamekey <fileId> <keyname> <newKeyName>
\r
512 # Renames <keyname> in <fileId> to <newKeyName>.
\r
515 # - This procedure doesn't write directly to the file, but to the
\r
516 # memory-version of the file. If directly the file (not memory version) is
\r
517 # modified after the call to iniparse:openfile, this procedure will not
\r
518 # see the changes in the file, but only changes in memory-version.
\r
520 # See: readini iniparse:openfile
\r
522 proc iniparse:renamekey {id oldkey newkey} {
\r
525 if {[lsearch $iniparse(idlist) $id] == -1} return ;# No such Id
\r
527 set fileline $iniparse($id,data)
\r
530 foreach line $fileline {
\r
531 if {$line=="\[$oldkey\]"} {
\r
532 lappend data "" "\[$newkey\]"
\r
535 if {[chrchk $line]} {lappend data "" $line} \
\r
536 else {lappend data $line}
\r
540 set iniparse($id,data) $data
\r