Update a configuration file: Difference between revisions

m
→‎{{header|11l}}: new way of specifying file open mode
(Added Delphi example)
m (→‎{{header|11l}}: new way of specifying file open mode)
 
(6 intermediate revisions by 5 users not shown)
Line 56:
* [[Read a configuration file]]
<br><br>
 
=={{header|11l}}==
{{trans|D}}
 
<syntaxhighlight lang="11l">T.enum EntryType
EMPTY
ENABLED
DISABLED
COMMENT
IGNORE
 
T Entry
EntryType etype
String name
String value
 
F (etype, name = ‘’, value = ‘’)
.etype = etype
.name = name
.value = value
 
T Config
String path
[Entry] entries
 
F (path)
.path = path
L(=line) File(path).read_lines()
line = line.ltrim(‘ ’)
I line.empty
.entries.append(Entry(EntryType.EMPTY))
E I line[0] == ‘#’
.entries.append(Entry(EntryType.COMMENT, line))
E
line = line.replace(re:‘[^a-zA-Z0-9\x20;]’, ‘’)
V m = re:‘^(;*)\s*([a-zA-Z0-9]+)\s*([a-zA-Z0-9]*)’.search(line)
I m & !m.group(2).empty
V t = I m.group(1).empty {EntryType.ENABLED} E EntryType.DISABLED
.addOption(m.group(2), m.group(3), t)
 
F enableOption(name)
Int? i = .getOptionIndex(name)
I i != N
.entries[i].etype = EntryType.ENABLED
 
F disableOption(name)
Int? i = .getOptionIndex(name)
I i != N
.entries[i].etype = EntryType.DISABLED
 
F setOption(name, value)
Int? i = .getOptionIndex(name)
I i != N
.entries[i].value = value
 
F addOption(name, val, t = EntryType.ENABLED)
.entries.append(Entry(t, name.uppercase(), val))
 
F removeOption(name)
Int? i = .getOptionIndex(name)
I i != N
.entries[i].etype = EntryType.IGNORE
 
F getOptionIndex(name) -> Int?
L(e) .entries
I e.etype !C (EntryType.ENABLED, EntryType.DISABLED)
L.continue
I e.name == name.uppercase()
R L.index
R N
 
F store()
V f = File(.path, WRITE)
L(e) .entries
I e.etype == EMPTY
f.write("\n")
E I e.etype == ENABLED
f.write("#. #.\n".format(e.name, e.value))
E I e.etype == DISABLED
f.write("; #. #.\n".format(e.name, e.value))
E I e.etype == COMMENT
f.write(e.name"\n")
 
V cfg = Config(‘config.txt’)
cfg.enableOption(‘seedsremoved’)
cfg.disableOption(‘needspeeling’)
cfg.setOption(‘numberofbananas’, ‘1024’)
cfg.addOption(‘numberofstrawberries’, ‘62000’)
cfg.store()</syntaxhighlight>
 
{{out}}
The same as in D.
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">; Author: AlephX, Aug 17 2011
data = %A_scriptdir%\rosettaconfig.txt
outdata = %A_scriptdir%\rosettaconfig.tmp
Line 149 ⟶ 241:
}
 
FileCopy, %A_scriptdir%\rosettaconfig.tmp, %A_scriptdir%\rosettaconfig.txt, 1</langsyntaxhighlight>
 
=={{header|BASIC}}==
Line 159 ⟶ 251:
 
This program is not tied to the task requested, but it can read and modify ANY configuration file. It is somewhat long, but includes functionality to modify or add variables and values to the configuration file, append remarks (#) to it, read and save values in an array (comma separated), toggle comment mode for variables in a configuration file, etc. It is even longer because is almost fully commented and in key procedures every parameter is explained. It includes a main program cycle to read the configuration file and modify its values.
<langsyntaxhighlight lang="qbasic">
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
' Read a Configuration File V1.0 '
Line 840 ⟶ 932:
YorN$ = sYorN
END FUNCTION
</syntaxhighlight>
</lang>
 
In the following example, the user can modify the variables, their comment status and add the NUMBEROFSTRAWBERRIES variable with the value of 64000. In this case, the user is modifying the value of the NUMBEROFBANANAS variable in the configuration file.
Line 869 ⟶ 961:
C with POSIX <code>strcasecmp</code> function for case-insensitive comparing. Substitute your toolchain's version.
 
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 935 ⟶ 1,027:
{ fprintf(stderr, "failed\n");
return (EXIT_FAILURE); }
return 0; }</langsyntaxhighlight>
 
Run:
Line 968 ⟶ 1,060:
=={{header|D}}==
This type of file is really not very suitable for automated management, so this code is very basic.
<langsyntaxhighlight lang="d">import std.stdio, std.file, std.string, std.regex, std.path,
std.typecons;
 
Line 1,080 ⟶ 1,172:
cfg.addOption("numberofstrawberries", "62000");
cfg.store();
}</langsyntaxhighlight>
Input file:
<pre># This is a configuration file in standard configuration file format
Line 1,137 ⟶ 1,229:
{{libheader| uSettings}}
Requere '''uSettings.pas''' found in [[Read_a_configuration_file#Delphi]].
<syntaxhighlight lang="delphi">
<lang Delphi>
program uConfigFile;
 
Line 1,170 ⟶ 1,262:
Settings.Free;
Readln;
end.</langsyntaxhighlight>
{{out}}
<pre> FAVOURITEFRUIT = banana
Line 1,180 ⟶ 1,272:
=={{header|Erlang}}==
Given the large number of very exact rules governing the update of this configuration file it is with some pleasure I add new options to the beginning of the file.
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( update_configuration_file ).
 
Line 1,275 ⟶ 1,367:
[Option | T] = string:tokens( String, " " ),
string:join( [string:to_upper(Option) | T], " " ).
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,307 ⟶ 1,399:
 
=={{header|Fortran}}==
Fortran has long had a built-in method for writing and reading a configuration file with ease, via the NAMELIST facility. The designers of the modern "configuration" files have paid not the slightest attention to the protocol, which is as follows: <langsyntaxhighlight Fortranlang="fortran"> PROGRAM TEST !Define some data aggregates, then write and read them.
CHARACTER*28 FAVOURITEFRUIT
LOGICAL NEEDSPEELING
Line 1,331 ⟶ 1,423:
READ (F,FRUIT) !Read who knows what.
WRITE (6,FRUIT)
END</langsyntaxhighlight>
Most of which is support stuff. The requirement is to declare a NAMELIST naming the variables of interest, then READ or WRITE using just the name of the NAMELIST. Only three statements, four if the file OPEN is counted.
 
Line 1,359 ⟶ 1,451:
In a more general situation, it is helpful to have a routine that reads the NAMELIST style input and isolates the assignments so that each can individually be written to a scratch file in the NAMELIST style (i.e. providing the block head and tail lines, though some Fortrans allow NAMELIST input from a text variable and without this requirement) whereupon if ERR is provoked during the READ, the troublesome entry can be displayed for user appreciation before continuing with any remaining assignments.
 
Otherwise, the old NAMELIST could be used for input, with the undesired value simply ignored within the new version of the programme. For output, a new NAMELIST would be devised omitting the unwanted name - the same variables can be named in more than one NAMELIST. However, every NAMELIST's name must be unique within a routine and this would be the new block header name. So, read the parameter file in one routine which declares the old NAMELIST, complete with the name of the now unwanted variable, but write it via another routine which declares the new NAMELIST using the same name but omitting the names of undesired variables. The wanted variables would be in COMMON, or with F90 onwards be common names in a MODULE, or one could mess with parameter lists. <langsyntaxhighlight Fortranlang="fortran"> MODULE MONKEYFODDER
INTEGER FIELD !An I/O unit number.
CHARACTER*28 FAVOURITEFRUIT
Line 1,391 ⟶ 1,483:
CALL GETVALS("Basket.txt") !Read the values, allowing for the previous version.
CALL PUTVALS("Basket.txt") !Save the values, as per the new version.
END</langsyntaxhighlight>
Whereupon the file now has
<pre>
Line 1,406 ⟶ 1,498:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
Type ConfigData
Line 1,510 ⟶ 1,602:
Print
Print "Press any key to quit"
Sleep</langsyntaxhighlight>
 
The contents of config2.txt after updating are:
Line 1,543 ⟶ 1,635:
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,746 ⟶ 1,838:
c.Set("NUMBEROFSTRAWBERRIES", "62000")
c.Write(os.Stdout)
}</langsyntaxhighlight>
 
=={{header|Haskell}}==
Line 1,752 ⟶ 1,844:
Necessary imports
 
<langsyntaxhighlight Haskelllang="haskell">import Data.Char (toUpper)
import qualified System.IO.Strict as S</langsyntaxhighlight>
 
Definition of datatypes:
 
<langsyntaxhighlight Haskelllang="haskell">data INI = INI { entries :: [Entry] } deriving Show
 
data Entry = Comment String
Line 1,783 ⟶ 1,875:
f : v -> field f (unwords v)
field f = Field (toUpper <$> f)
flag f = Flag (toUpper <$> f)</langsyntaxhighlight>
 
Getting and setting fields in INI data:
 
<langsyntaxhighlight Haskelllang="haskell">setValue :: String -> String -> INI -> INI
setValue f v = INI . replaceOn (eqv f) (Field f v) . entries
 
Line 1,805 ⟶ 1,897:
(prev,post) = case break p lst of
(lst, []) -> (lst, [])
(lst, _:xs) -> (lst, xs)</langsyntaxhighlight>
 
IO stuff:
 
<langsyntaxhighlight Haskelllang="haskell">readIni :: String -> IO INI
readIni file = INI . map read . lines <$> S.readFile file
 
Line 1,822 ⟶ 1,914:
enable "SeedsRemoved" .
setValue "NumberOfBananas" "1024" .
setValue "NumberOfStrawberries" "62000"</langsyntaxhighlight>
 
=={{header|J}}==
Line 1,828 ⟶ 1,920:
Since the task does not specify the line end character, we assume that the last character in the file is the line end character.
 
<langsyntaxhighlight Jlang="j">require 'regex strings'
 
normalize=:3 :0
Line 1,863 ⟶ 1,955:
upd=. y,' ',":x
(<m) 1!:2~ normalize (,upd,{:);<@rxrplc~&(pat;upd) t
)</langsyntaxhighlight>
 
Note that, aside from the line end issue, the task is ambiguous because it specifies a set of operations rather than a file format. If the consequences of these ambiguities are troubling, you might prefer to replace normalize with normalize^:_
Line 1,869 ⟶ 1,961:
Example use:
 
<langsyntaxhighlight Jlang="j"> 'example.file' disable 'needspeeling'
'example.file' enable 'seedsremoved'
1024 'example.file' set 'numberofbananas'
62000 'example.file' set 'numberofstrawberries'</langsyntaxhighlight>
 
Here's how the file specified in the task description looks after these steps have been executed:
Line 1,907 ⟶ 1,999:
{{trans|D}}
{{works with|Java|7}}
<langsyntaxhighlight lang="java">import java.io.*;
import java.util.*;
import java.util.regex.*;
Line 2,040 ⟶ 2,132:
}
}
}</langsyntaxhighlight>
 
Input file:
Line 2,100 ⟶ 2,192:
=={{header|Julia}}==
Designed similarly to the way multiple small functions in a Julia module for general editing of this file type might be written.
<langsyntaxhighlight lang="julia">function cleansyntax(line)
line = strip(line)
if line == ""
Line 2,204 ⟶ 2,296:
end
end
</langsyntaxhighlight> {{output}} <pre>
Contents of the revised file:
# This is a configuration file in standard configuration file format
Line 2,235 ⟶ 2,327:
=={{header|Kotlin}}==
{{trans|FreeBASIC}}
<langsyntaxhighlight lang="scala">// version 1.2.0
 
import java.io.File
Line 2,334 ⟶ 2,426:
val cData = ConfigData("banana", false, true, 1024, 62000)
updateConfigFile(fileName, cData)
}</langsyntaxhighlight>
 
Contents of file 'config.txt' after updating:
Line 2,367 ⟶ 2,459:
=={{header|Lasso}}==
Config type definition
<langsyntaxhighlight Lassolang="lasso">#!/usr/bin/lasso9
 
define config => type {
Line 2,465 ⟶ 2,557:
}
 
}</langsyntaxhighlight>
 
How to call it:
<syntaxhighlight lang="lasso">
<lang Lasso>
local(
config = config,
Line 2,483 ⟶ 2,575:
#config -> set('numberofbananas', 1024)
 
#config -> write</langsyntaxhighlight>
 
Initial config file:
Line 2,557 ⟶ 2,649:
NUMBEROFSTRAWBERRIES 62000
</pre>
 
=={{header|Nim}}==
{{trans|D}}
<syntaxhighlight lang="nim">import os, re, strutils
 
let regex = re(r"^(;*)\s*([A-Z0-9]+)\s*([A-Z0-9]*)", {reIgnoreCase, reStudy})
 
type
 
EntryType {.pure.} = enum Empty, Enabled, Disabled, Comment, Ignore
 
Entry = object
etype: EntryType
name: string
value: string
 
Config = object
entries: seq[Entry]
path: string
 
 
# Forward reference.
proc addOption*(config: var Config; name, value: string; etype = Enabled)
 
 
proc initConfig*(path: string): Config =
 
if not path.isValidFilename:
raise newException(IOError, "invalid file name.")
 
result.path = path
if not path.fileExists: return
 
for line in path.lines:
var line = line.strip
if line.len == 0:
result.entries.add Entry(etype: Empty)
elif line[0] == '#':
result.entries.add Entry(etype: Comment, value: line)
else:
line = line.replace(re"^a-zA-Z0-9\x20;")
var matches = newSeq[string](3)
if line.match(regex, matches) and matches[1].len != 0:
let etype = if matches[0].len == 0: Enabled else: Disabled
result.addOption(matches[1], matches[2], etype)
 
 
proc getOptionIndex(config: Config; name: string): int =
for i, e in config.entries:
if e.etype notin [Enabled, Disabled]: continue
if e.name == name.toUpperAscii:
return i
result = -1
 
 
proc enableOption*(config: var Config; name: string) =
let i = config.getOptionIndex(name)
if i >= 0:
config.entries[i].etype = Enabled
 
 
proc disableOption*(config: var Config; name: string) =
let i = config.getOptionIndex(name)
if i >= 0:
config.entries[i].etype = Disabled
 
 
proc setOption*(config: var Config; name, value: string) =
let i = config.getOptionIndex(name)
if i >= 0:
config.entries[i].value = value
 
 
proc addOption*(config: var Config; name, value: string; etype = Enabled) =
config.entries.add Entry(etype: etype, name: name.toUpperAscii, value: value)
 
 
proc removeOption*(config: var Config; name: string) =
let i = config.getOptionIndex(name)
if i >= 0:
config.entries[i].etype = Ignore
 
 
proc store*(config: Config) =
let f = open(config.path, fmWrite)
for e in config.entries:
case e.etype
of Empty: f.writeLine("")
of Enabled: f.writeLine(e.name, ' ', e.value)
of Disabled: f.writeLine("; ", e.name, ' ', e.value)
of Comment: f.writeLine(e.value)
of Ignore: discard
 
 
when isMainModule:
 
var cfg = initConfig("update_demo.config")
cfg.enableOption("seedsremoved")
cfg.disableOption("needspeeling")
cfg.setOption("numberofbananas", "1024")
cfg.addOption("numberofstrawberries", "62000")
cfg.store()</syntaxhighlight>
 
{{out}}
Original file:
<pre># This is a configuration file in standard configuration file format
#
# Lines begininning with a hash or a semicolon are ignored by the application
# program. Blank lines are also ignored by the application program.
 
# The first word on each non comment line is the configuration option.
# Remaining words or numbers on the line are configuration parameter
# data fields.
 
# Note that configuration option names are not case sensitive. However,
# configuration parameter data is case sensitive and the lettercase must
# be preserved.
 
# This is a favourite fruit
FAVOURITEFRUIT banana
 
# This is a boolean that should be set
NEEDSPEELING
 
# This boolean is commented out
; SEEDSREMOVED
 
# How many bananas we have
NUMBEROFBANANAS 48</pre>
 
Modified file:
<pre># This is a configuration file in standard configuration file format
#
# Lines begininning with a hash or a semicolon are ignored by the application
# program. Blank lines are also ignored by the application program.
 
# The first word on each non comment line is the configuration option.
# Remaining words or numbers on the line are configuration parameter
# data fields.
 
# Note that configuration option names are not case sensitive. However,
# configuration parameter data is case sensitive and the lettercase must
# be preserved.
 
# This is a favourite fruit
FAVOURITEFRUIT banana
 
# This is a boolean that should be set
; NEEDSPEELING
 
# This boolean is commented out
SEEDSREMOVED
 
# How many bananas we have
NUMBEROFBANANAS 1024
NUMBEROFSTRAWBERRIES 62000</pre>
 
Differences:
<pre>18c18
< NEEDSPEELING
---
> ; NEEDSPEELING
21c21
< ; SEEDSREMOVED
---
> SEEDSREMOVED
24c24,25
< NUMBEROFBANANAS 48
---
> NUMBEROFBANANAS 1024
> NUMBEROFSTRAWBERRIES 62000</pre>
 
=={{header|Perl}}==
 
<langsyntaxhighlight Perllang="perl">use warnings;
use strict;
 
Line 2,657 ⟶ 2,920:
 
# How many bananas we have
NUMBEROFBANANAS 48</langsyntaxhighlight>
 
=={{header|Phix}}==
Very basic (and contains most of the code from the read configuration file example)<br>
Note in particular there is no real attempt to distinguish between booleans and integers.
<!--<syntaxhighlight lang="phix">-->
<lang Phix>integer fn = open("RCTEST.INI","r")
<span style="color: #004080;">integer</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"RCTEST.INI"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"r"</span><span style="color: #0000FF;">)</span>
sequence lines = get_text(fn,GT_LF_STRIPPED)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_text</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #004600;">GT_LF_STRIPPED</span><span style="color: #0000FF;">)</span>
close(fn)
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
constant dini = new_dict()
<span style="color: #008080;">constant</span> <span style="color: #000000;">dini</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">new_dict</span><span style="color: #0000FF;">()</span>
for i=1 to length(lines) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
string li = trim(lines[i])
<span style="color: #004080;">string</span> <span style="color: #000000;">li</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
if length(li)
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">)</span>
and not find(li[1],"#;") then
<span style="color: #008080;">and</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"#;"</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
integer k = find(' ',li)
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">li</span><span style="color: #0000FF;">)</span>
if k!=0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
string rest = li[k+1..$]
<span style="color: #004080;">string</span> <span style="color: #000000;">rest</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]</span>
li = upper(li[1..k-1])
<span style="color: #000000;">li</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
putd(li,rest,dini)
<span style="color: #7060A8;">putd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rest</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span>
else
<span style="color: putd(upper(li),1,dini)#008080;">else</span>
<span style="color: #7060A8;">putd</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">),</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
 
deld("NEEDSPEELING",dini)
<span style="color: #7060A8;">deld</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"NEEDSPEELING"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span>
setd("SEEDSREMOVED",1,dini)
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"SEEDSREMOVED"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span>
setd("NUMBEROFBANANAS",1024,dini)
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"NUMBEROFBANANAS"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1024</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span>
setd("NUMBEROFSTRAWBERRIES",62000,dini)
<span style="color: #7060A8;">setd</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"NUMBEROFSTRAWBERRIES"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">62000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span>
 
for i=1 to length(lines) do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
string li = trim(lines[i])
<span style="color: #004080;">string</span> <span style="color: #000000;">li</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
if length(li)
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">)</span>
and li[1]!='#' then
<span style="color: #008080;">and</span> <span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">'#'</span> <span style="color: #008080;">then</span>
if li[1]=';' then
<span style="color: #008080;">if</span> <span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">';'</span> <span style="color: #008080;">then</span>
li = trim(li[2..$])
<span style="color: #000000;">li</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trim</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$])</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
integer k = find(' ',li)
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #000000;">li</span><span style="color: #0000FF;">)</span>
if k!=0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
string rest = li[k+1..$]
<span style="color: #004080;">string</span> <span style="color: #000000;">rest</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]</span>
li = upper(li[1..k-1])
<span style="color: #000000;">li</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
k = getd_index(li,dini)
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span>
if k=0 then
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
lines[i] = "; "&li&" "&rest
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"; "</span><span style="color: #0000FF;">&</span><span style="color: #000000;">li</span><span style="color: #0000FF;">&</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">&</span><span style="color: #000000;">rest</span>
else
<span object o style="color: getd_by_index(k,dini)#008080;">else</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">o</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">getd_by_index</span><span style="color: #0000FF;">(</span><span style="color: #000000;">k</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span>
if not string(o) then o = sprint(o) end if
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000000;">o</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">o</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
lines[i] = li&" "&o
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">li</span><span style="color: #0000FF;">&</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">&</span><span style="color: #000000;">o</span>
deld(li,dini)
<span style="color: #7060A8;">deld</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
else
<span style="color: if getd(li,dini) then#008080;">else</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">getd</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
lines[i] = li
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">li</span>
deld(li,dini)
<span style="color: #7060A8;">deld</span><span style="color: #0000FF;">(</span><span style="color: #000000;">li</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span>
else
<span lines[i] style="color: "#008080; "&li>else</span>
<span style="color: #000000;">lines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"; "</span><span style="color: #0000FF;">&</span><span style="color: #000000;">li</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
function visitor(object key, object data, object /*user_data*/)
<span style="color: #008080;">function</span> <span style="color: #000000;">visitor</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">key</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">data</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000080;font-style:italic;">/*user_data*/</span><span style="color: #0000FF;">)</span>
lines = append(lines,key&" "&sprint(data))
<span style="color: #000000;">lines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">key</span><span style="color: #0000FF;">&</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">sprint</span><span style="color: #0000FF;">(</span><span style="color: #000000;">data</span><span style="color: #0000FF;">))</span>
return 1
<span style="color: #008080;">return</span> <span style="color: #000000;">1</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
traverse_dict(routine_id("visitor"),0,dini)
<span style="color: #7060A8;">traverse_dict</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"visitor"</span><span style="color: #0000FF;">),</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">dini</span><span style="color: #0000FF;">)</span>
fn = open("RCTEST.INI","w")
<span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">open</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"RCTEST.INI"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"w"</span><span style="color: #0000FF;">)</span>
puts(fn,join(lines,"\n"))
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lines</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">))</span>
close(fn)</lang>
<span style="color: #7060A8;">close</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
Resulting RCTEST.INI file:
<pre>
Line 2,755 ⟶ 3,020:
=={{header|PHP}}==
 
<langsyntaxhighlight PHPlang="php"><?php
 
$conf = file_get_contents('update-conf-file.txt');
Line 2,775 ⟶ 3,040:
}
 
echo $conf;</langsyntaxhighlight>
 
{{in}}
Line 2,831 ⟶ 3,096:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(let Data # Read all data
(in "config"
(make
Line 2,886 ⟶ 3,151:
(out "config"
(for L Data
(prinl (glue " " (if (car L) L (cdr L)))) ) ) )</langsyntaxhighlight>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Update-ConfigurationFile
{
Line 2,997 ⟶ 3,262:
}
}
</syntaxhighlight>
</lang>
<syntaxhighlight lang="powershell">
<lang PowerShell>
Update-ConfigurationFile -NumberOfStrawberries 62000 -NumberOfBananas 1024 -SeedsRemoved On -NeedsPeeling Off
 
Invoke-Item -Path ".\config.txt"
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 3,035 ⟶ 3,300:
 
=={{header|Python}}==
<langsyntaxhighlight Pythonlang="python">#!/usr/bin/env python
 
#----------------------------------------------------------------------------
Line 3,253 ⟶ 3,518:
cfg.enable_option('numberofstrawberries', 62000)
print cfg
</syntaxhighlight>
</lang>
 
Output:
Line 3,289 ⟶ 3,554:
Use the shared <tt>[[Racket/Options|options.rkt]]</tt> code.
 
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
 
Line 3,308 ⟶ 3,573:
;; numberofstrawberries with a value of 62000
(set! numberofstrawberries 62000)
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 3,320 ⟶ 3,585:
The script:
 
<syntaxhighlight lang="raku" perl6line>use File::Temp;
 
my ($tmpfile, $out) = tempfile;
Line 3,354 ⟶ 3,619:
sub format-line ($key, $value, $enabled) {
("; " if !$enabled) ~ $key.uc ~ (" $value" if defined $value);
}</langsyntaxhighlight>
 
=={{header|REXX}}==
Line 3,367 ⟶ 3,632:
 
Programming note: &nbsp; not all REXXes support the closing of files using the &nbsp; '''lineout''' &nbsp; BIF with a single argument.
<langsyntaxhighlight lang="rexx">/*REXX program demonstrates how to update a configuration file (four specific tasks).*/
parse arg iFID oFID . /*obtain optional arguments from the CL*/
if iFID=='' | iFID=="," then iFID= 'UPDATECF.TXT' /*Not given? Then use default.*/
Line 3,411 ⟶ 3,676:
cpy: call lineout oFID, arg(1); return /*write one line of text ───► oFID. */
dos: ''arg(1) word(arg(2) "2>nul",1); return /*execute a DOS command (quietly). */
new: z=arg(1); changed=1; return /*use new Z, indicate changed record. */</langsyntaxhighlight>
'''output''' &nbsp; when using the default input file (which has additional removable statements) and input options:
<pre>
Line 3,474 ⟶ 3,739:
 
===version 2===
<langsyntaxhighlight lang="rexx">fid='updatecf.txt'
oid='updatecf.xxx'; 'erase' oid
options=translate('FAVOURITEFRUIT NEEDSPEELING SEEDSREMOVED NUMBEROFBANANAS numberofstrawberries')
Line 3,516 ⟶ 3,781:
done.option=1
End
Return </langsyntaxhighlight>
{{out}}
same as for solution 'D'
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">require 'stringio'
 
class ConfigFile
Line 3,660 ⟶ 3,925:
 
# How many bananas we have
NUMBEROFBANANAS 48</langsyntaxhighlight>
outputs
<pre># This is a configuration file in standard configuration file format
Line 3,691 ⟶ 3,956:
=={{header|Tcl}}==
Creating this to be a general solution:
<langsyntaxhighlight lang="tcl">package require Tcl 8.6
oo::class create Config {
variable filename contents
Line 3,766 ⟶ 4,031:
}
}
}</langsyntaxhighlight>
Applying to the task at hand (assuming a file in the current directory called <tt>sample.cfg</tt>):
<langsyntaxhighlight lang="tcl">set cfg [Config new "sample.cfg"]
$cfg disable needspeeling
$cfg enable seedsremoved
$cfg set numberofbananas 1024
$cfg set numberofstrawberries 62000
$cfg save</langsyntaxhighlight>
 
=={{header|TXR}}==
Line 3,789 ⟶ 4,054:
This works by reading the configuration into a variable, and then making multiple passes over it, using the same constructs that normally operate on files or pipes. The first 30% of the script deals with reading the configuration file and parsing each command line argument, and converting its syntax into configuration syntax, stored in <code>new_opt_line</code>. For each argument, the configuration is then scanned and filtered from <code>config</code> to <code>new_config</code>, using the same syntax which could be used to do the same job with temporary files. When the interesting variable is encountered in the config, using one of the applicable pattern matches, then the prepared configuration line is substituted for it. While this is going on, the encountered variable names (bindings for <code>var_other</code>) are also being collected into a list. This list is then later used to check via the directive <code>@(bind opt_there option)</code> to determine whether the option occurred in the configuration or not. The bind construct will not only check whether the left and right hand side are equal, but if nested lists are involved, it checks whether either side occurs in the other as a subtree. <code>option</code> binds with <code>opt_other</code> if it matches one of the option names in <code>opt_other</code>. Finally, the updated config is regurgitated.
 
<langsyntaxhighlight lang="txr">@(next :args)
@configfile
@(maybe)
Line 3,864 ⟶ 4,129:
@config
@ (end)
@(end)</langsyntaxhighlight>
 
Sample invocation:
Line 3,915 ⟶ 4,180:
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">
<lang vb>
Set objFSO = CreateObject("Scripting.FileSystemObject")
 
Line 3,973 ⟶ 4,238:
Set objFSO = Nothing
Set objParamLookup = Nothing
</syntaxhighlight>
</lang>
 
{{In}}
Line 4,005 ⟶ 4,270:
 
{{Out}}
<pre>
# This is a configuration file in standard configuration file format
#
# Lines begininning with a hash or a semicolon are ignored by the application
# program. Blank lines are also ignored by the application program.
 
# The first word on each non comment line is the configuration option.
# Remaining words or numbers on the line are configuration parameter
# data fields.
 
# Note that configuration option names are not case sensitive. However,
# configuration parameter data is case sensitive and the lettercase must
# be preserved.
 
# This is a favourite fruit
FAVOURITEFRUIT banana
 
# This is a boolean that should be set
; NEEDSPEELING
 
# This boolean is commented out
SEEDSREMOVED
 
# How many bananas we have
NUMBEROFBANANAS 1024
NUMBEROFSTRAWBERRIES 62000
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-ioutil}}
{{libheader|Wren-dynamic}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "io" for File
import "./ioutil" for FileUtil
import "./dynamic" for Tuple
import "./str" for Str
 
var fields = ["favouriteFruit", "needsPeeling", "seedsRemoved", "numberOfBananas", "numberOfStrawberries"]
var ConfigData = Tuple.create("ConfigData", fields)
 
var updateConfigFile = Fn.new { |fileName, cData|
var lines = File.read(fileName).trimEnd().split(FileUtil.lineBreak)
var tempFileName = "temp_%(fileName)"
var out = File.create(tempFileName)
var hadFruit = false
var hadPeeling = false
var hadSeeds = false
var hadBananas = false
var hadStrawberries = false
 
for (line in lines) {
var cont = false
if (line.isEmpty || line[0] == "#") {
out.writeBytes(line + "\n")
cont = true
}
if (!cont) {
var ln = Str.upper(line.trimStart(";").trim())
if (!ln.isEmpty) {
if (ln.take(14).join() == "FAVOURITEFRUIT") {
if (!hadFruit) {
hadFruit = true
out.writeBytes("FAVOURITEFRUIT %(cData.favouriteFruit)\n")
}
} else if (ln.take(12).join() == "NEEDSPEELING") {
if (!hadPeeling) {
hadPeeling = true
if (cData.needsPeeling) {
out.writeBytes("NEEDSPEELING\n")
} else {
out.writeBytes("; NEEDSPEELING\n")
}
}
} else if (ln.take(12).join() == "SEEDSREMOVED") {
if (!hadSeeds) {
hadSeeds = true
if (cData.seedsRemoved) {
out.writeBytes("SEEDSREMOVED\n")
} else {
out.writeBytes("; SEEDSREMOVED\n")
}
}
} else if (ln.take(15).join() == "NUMBEROFBANANAS") {
if (!hadBananas) {
hadBananas = true
out.writeBytes("NUMBEROFBANANAS %(cData.numberOfBananas)\n")
}
} else if (ln.take(20).join() == "NUMBEROFSTRAWBERRIES") {
if (!hadStrawberries) {
hadStrawberries = true
out.writeBytes("NUMBEROFSTRAWBERRIES %(cData.numberOfStrawberries)\n")
}
}
}
}
}
 
if (!hadFruit) {
out.writeBytes("FAVOURITEFRUIT %(cData.favouriteFruit)\n")
}
 
if (!hadPeeling) {
if (cData.needsPeeling) {
out.writeBytes("NEEDSPEELING\n")
} else {
out.writeBytes("; NEEDSPEELING\n")
}
}
 
if (!hadSeeds) {
if (cData.seedsRemoved) {
out.writeBytes("SEEDSREMOVED\n")
} else {
out.writeBytes("; SEEDSREMOVED\n")
}
}
 
if (!hadBananas) {
out.writeBytes("NUMBEROFBANANAS %(cData.numberOfBananas)\n")
}
 
if (!hadStrawberries) {
out.writeBytes("NUMBEROFSTRAWBERRIES %(cData.numberOfStrawberries)\n")
}
 
out.close()
FileUtil.move(tempFileName, fileName, true)
}
 
var fileName = "config.txt"
var cData = ConfigData.new("banana", false, true, 1024, 62000)
updateConfigFile.call(fileName, cData)</syntaxhighlight>
 
{{out}}
<pre>
# This is a configuration file in standard configuration file format
1,480

edits