September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -32,6 +32,7 @@ For this task, we have a configuration file as follows:
|
|||
|
||||
OTHERFAMILY Rhu Barber, Harry Barber
|
||||
|
||||
|
||||
For the task we need to set four variables according to the configuration entries as follows:
|
||||
|
||||
*fullname = Foo Barber
|
||||
|
|
@ -39,11 +40,13 @@ For the task we need to set four variables according to the configuration entrie
|
|||
*needspeeling = true
|
||||
*seedsremoved = false
|
||||
|
||||
|
||||
We also have an option that contains multiple parameters. These may be stored in an array.
|
||||
|
||||
* otherfamily(1) = Rhu Barber
|
||||
* otherfamily(2) = Harry Barber
|
||||
|
||||
'''See also:'''
|
||||
|
||||
;Related tasks
|
||||
* [[Update a configuration file]]
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
with Ada.Strings.Unbounded;
|
||||
with Config_File_Parser;
|
||||
pragma Elaborate_All (Config_File_Parser);
|
||||
|
||||
package Config is
|
||||
|
||||
function TUS (S : String) return Ada.Strings.Unbounded.Unbounded_String
|
||||
renames Ada.Strings.Unbounded.To_Unbounded_String;
|
||||
-- Convenience rename. TUS is much shorter than To_Unbounded_String.
|
||||
|
||||
type Keys is (
|
||||
FULLNAME,
|
||||
FAVOURITEFRUIT,
|
||||
NEEDSPEELING,
|
||||
SEEDSREMOVED,
|
||||
OTHERFAMILY);
|
||||
-- These are the valid configuration keys.
|
||||
|
||||
type Defaults_Array is
|
||||
array (Keys) of Ada.Strings.Unbounded.Unbounded_String;
|
||||
-- The array type we'll use to hold our default configuration settings.
|
||||
|
||||
Defaults_Conf : Defaults_Array :=
|
||||
(FULLNAME => TUS ("John Doe"),
|
||||
FAVOURITEFRUIT => TUS ("blackberry"),
|
||||
NEEDSPEELING => TUS ("False"),
|
||||
SEEDSREMOVED => TUS ("False"),
|
||||
OTHERFAMILY => TUS ("Daniel Defoe, Ada Byron"));
|
||||
-- Default values for the Program object. These can be overwritten by
|
||||
-- the contents of the rosetta.cfg file(see below).
|
||||
|
||||
package Rosetta_Config is new Config_File_Parser (
|
||||
Keys => Keys,
|
||||
Defaults_Array => Defaults_Array,
|
||||
Defaults => Defaults_Conf,
|
||||
Config_File => "rosetta.cfg");
|
||||
-- Instantiate the Config configuration object.
|
||||
|
||||
end Config;
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
with Ada.Text_IO;
|
||||
with Config; use Config;
|
||||
|
||||
procedure Read_Config is
|
||||
use Ada.Text_IO;
|
||||
use Rosetta_Config;
|
||||
|
||||
begin
|
||||
New_Line;
|
||||
Put_Line ("Reading Configuration File.");
|
||||
Put_Line ("Fullname := " & Get (Key => FULLNAME));
|
||||
Put_Line ("Favorite Fruit := " & Get (Key => FAVOURITEFRUIT));
|
||||
Put_Line ("Other Family := " & Get (Key => OTHERFAMILY));
|
||||
if Has_Value (Key => NEEDSPEELING) then
|
||||
Put_Line ("NEEDSPEELLING := " & Get (Key => NEEDSPEELING));
|
||||
else
|
||||
Put_Line ("NEEDSPEELLING := True");
|
||||
end if;
|
||||
if Has_Value (Key => SEEDSREMOVED) then
|
||||
Put_Line ("SEEDSREMOVED := " & Get (Key => SEEDSREMOVED));
|
||||
else
|
||||
Put_Line ("SEEDSREMOVED := True");
|
||||
end if;
|
||||
end Read_Config;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
with Config; use Config;
|
||||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
|
||||
procedure Rosetta_Read_Cfg is
|
||||
cfg: Configuration:= Init("rosetta_read.cfg", Case_Sensitive => False, Variable_Terminator => ' ');
|
||||
fullname : String := cfg.Value_Of("*", "fullname");
|
||||
favouritefruit : String := cfg.Value_Of("*", "favouritefruit");
|
||||
needspeeling : Boolean := cfg.Is_Set("*", "needspeeling");
|
||||
seedsremoved : Boolean := cfg.Is_Set("*", "seedsremoved");
|
||||
otherfamily : String := cfg.Value_Of("*", "otherfamily");
|
||||
begin
|
||||
Put_Line("fullname = " & fullname);
|
||||
Put_Line("favouritefruit = " & favouritefruit);
|
||||
Put_Line("needspeeling = " & Boolean'Image(needspeeling));
|
||||
Put_Line("seedsremoved = " & Boolean'Image(seedsremoved));
|
||||
Put_Line("otherfamily = " & otherfamily);
|
||||
end;
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
record r, s;
|
||||
integer c;
|
||||
file f;
|
||||
list l;
|
||||
text an, d, k;
|
||||
|
||||
an = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
f_affix(f, "tmp/config");
|
||||
|
||||
while ((c = f_peek(f)) ^ -1) {
|
||||
integer removed;
|
||||
|
||||
f_side(f, " \t\r");
|
||||
c = f_peek(f);
|
||||
removed = c == ';';
|
||||
if (removed) {
|
||||
f_pick(f);
|
||||
f_side(f, " \t\r");
|
||||
c = f_peek(f);
|
||||
}
|
||||
c = index(an, c);
|
||||
if (-1 < c && c < 52) {
|
||||
f_near(f, an, k);
|
||||
if (removed) {
|
||||
r[k] = "false";
|
||||
} else {
|
||||
data b;
|
||||
|
||||
f_side(f, " \t\r");
|
||||
if (f_peek(f) == '=') {
|
||||
f_pick(f);
|
||||
f_side(f, " \t\r");
|
||||
}
|
||||
f_ever(f, ",#\n", d);
|
||||
b = d;
|
||||
bb_drop(b, " \r\t");
|
||||
d = b_string(b);
|
||||
if (f_peek(f) != ',') {
|
||||
r[k] = length(d) ? d : "true";
|
||||
} else {
|
||||
f_news(f, l, 0, 0, ",");
|
||||
lf_push(l, d);
|
||||
for (c, d in l) {
|
||||
b = d;
|
||||
bb_drop(b, " \r\t");
|
||||
bf_drop(b, " \r\t");
|
||||
l[c] = b_string(b);
|
||||
}
|
||||
r_put(s, k, l);
|
||||
f_seek(f, -1, SEEK_CURRENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f_slip(f);
|
||||
}
|
||||
|
||||
r_wcall(r, o_, 0, 2, ": ", "\n");
|
||||
|
||||
for (k, l in s) {
|
||||
o_(k, ": ");
|
||||
l_ucall(l, o_, 0, ", ");
|
||||
o_("\n");
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
Public Sub Form_Open()
|
||||
Dim fullname As String = Settings["fullname", "Foo Barber"] 'If fullname is empty then use the default "Foo Barber"
|
||||
Dim favouritefruit As String = Settings["favouritefruit", "banana"]
|
||||
Dim needspeeling As String = Settings["needspeling", True]
|
||||
Dim seedsremoved As String = Settings["seedsremoved", False]
|
||||
Dim otherfamily As String[] = Settings["otherfamily", ["Rhu Barber", "Harry Barber"]]
|
||||
|
||||
Print fullname
|
||||
|
||||
'To save
|
||||
Settings["fullname"] = "John Smith"
|
||||
fullname = Settings["fullname"]
|
||||
|
||||
Print fullname
|
||||
|
||||
End
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
def parse:
|
||||
|
||||
def uc: .name | ascii_upcase;
|
||||
|
||||
def parse_boolean:
|
||||
capture( "(?<name>^[^ ] *$)" )
|
||||
| { (uc) : true };
|
||||
|
||||
def parse_var_value:
|
||||
capture( "(?<name>^[^ ]+)[ =] *(?<value>[^,]+ *$)" )
|
||||
| { (uc) : .value };
|
||||
|
||||
def parse_var_array:
|
||||
capture( "(?<name>^[^ ]+)[ =] *(?<value>.*)" )
|
||||
| { (uc) : (.value | sub(" +$";"") | [splits(", *")]) };
|
||||
|
||||
reduce inputs as $i ({};
|
||||
if $i|length == 0 or test("^[#;]") then .
|
||||
else . + ($i | ( parse_boolean // parse_var_value // parse_var_array // {} ))
|
||||
end);
|
||||
|
||||
parse
|
||||
|
|
@ -1,38 +1,37 @@
|
|||
import java.nio.charset.StandardCharsets
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
|
||||
data class Configuration(val map: Map<String, Any?>) {
|
||||
val fullName: String by Delegates.mapVal(map)
|
||||
val favoriteFruit: String by Delegates.mapVal(map)
|
||||
val needsPeeling: Boolean by Delegates.mapVal(map)
|
||||
val otherFamily: List<String> by Delegates.mapVal(map)
|
||||
val fullName: String by map
|
||||
val favoriteFruit: String by map
|
||||
val needsPeeling: Boolean by map
|
||||
val otherFamily: List<String> by map
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val configurationPath = Paths.get(args[0])!!
|
||||
val lines = Files.readAllLines(Paths.get("src/configuration.txt"), StandardCharsets.UTF_8)
|
||||
val keyValuePairs = lines.map{ it.trim() }
|
||||
.filterNot { it.isEmpty() }
|
||||
.filterNot(::commentedOut)
|
||||
.map(::toKeyValuePair)
|
||||
|
||||
val configurables = Files.readAllLines(configurationPath, StandardCharsets.UTF_8)
|
||||
.map { it.trim() }
|
||||
.filterNot { it.isEmpty() }
|
||||
.filterNot(::commentedOut)
|
||||
.map(::toKeyValuePairs)
|
||||
|
||||
val configurationMap: MutableMap<String, Any?> = hashMapOf("needsPeeling" to false)
|
||||
for (configurable in configurables) {
|
||||
val (key, value) = configurable
|
||||
val configurationMap = hashMapOf<String, Any>("needsPeeling" to false)
|
||||
for (pair in keyValuePairs) {
|
||||
val (key, value) = pair
|
||||
when (key) {
|
||||
"FULLNAME" -> configurationMap.put("fullName", value)
|
||||
"FAVOURITEFRUIT" -> configurationMap.put("favoriteFruit", value)
|
||||
"NEEDSPEELING" -> configurationMap.put("needsPeeling", true)
|
||||
"OTHERFAMILY" -> configurationMap.put("otherFamily", value.split(" , ").map { it.trim() })
|
||||
else -> println("Encountered unexpected key ${key}=${value}")
|
||||
else -> println("Encountered unexpected key $key=$value")
|
||||
}
|
||||
}
|
||||
|
||||
val configuration = Configuration(configurationMap)
|
||||
println(Configuration(configurationMap))
|
||||
}
|
||||
|
||||
private fun commentedOut(line: String): Boolean = (line.indexOf("#") == 0 || line.indexOf(";") == 0)
|
||||
private fun commentedOut(line: String) = line.startsWith("#") || line.startsWith(";")
|
||||
|
||||
private fun toKeyValuePairs(line: String): Pair<String, String> {
|
||||
return line.split(" ", 2).let {
|
||||
Pair(it[0], if (it.size == 1) "" else it[1])
|
||||
}
|
||||
private fun toKeyValuePair(line: String) = line.split(Regex(" "), 2).let {
|
||||
Pair(it[0], if (it.size == 1) "" else it[1])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
integer fn = open("RCTEST.INI","r")
|
||||
sequence lines = get_text(fn,GT_LF_STRIPPED)
|
||||
close(fn)
|
||||
constant dini = new_dict()
|
||||
for i=1 to length(lines) do
|
||||
string li = trim(lines[i])
|
||||
if length(li)
|
||||
and not find(li[1],"#;") then
|
||||
integer k = find(' ',li)
|
||||
if k!=0 then
|
||||
string rest = li[k+1..$]
|
||||
li = li[1..k-1] -- (may want upper())
|
||||
if find(',',rest) then
|
||||
sequence a = split(rest,',')
|
||||
for j=1 to length(a) do a[j]=trim(a[j]) end for
|
||||
putd(li,a,dini)
|
||||
else
|
||||
putd(li,rest,dini)
|
||||
end if
|
||||
else
|
||||
putd(li,1,dini) -- ""
|
||||
end if
|
||||
end if
|
||||
end for
|
||||
|
||||
function visitor(object key, object data, object /*user_data*/)
|
||||
?{key,data}
|
||||
return 1
|
||||
end function
|
||||
traverse_dict(routine_id("visitor"),0,dini)
|
||||
?getd("FAVOURITEFRUIT",dini)
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
(de rdConf (File)
|
||||
(pipe (in File (while (echo "#" ";") (till "^J")))
|
||||
(while (read)
|
||||
(skip)
|
||||
(set @ (or (line T) T)) ) ) )
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
(off FULLNAME FAVOURITEFRUIT NEEDSPEELING SEEDSREMOVED OTHERFAMILY)
|
||||
(rdConf "conf.txt")
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<@ DEFUDRLIT>__ReadConfigurationFile|
|
||||
<@ LETSCPPNTPARSRC>Data|1</@><@ OMT> read file into locally scope variable</@>
|
||||
<@ LETCGDLSTLLOSCP>List|Data</@><@ OMT> split Data into a list of lines </@>
|
||||
<@ OMT> Remove comment lines, and blank lines </@>
|
||||
<@ ACTOVRBEFLSTLIT>List|;</@>
|
||||
<@ ACTOVRBEFLSTLIT>List|#</@>
|
||||
<@ ACTRMELST>List</@>
|
||||
<@ OMT> Iterate over the lines of the list </@>
|
||||
<@ ITEENULSTLit>List|
|
||||
<@ LETVARUPTVALLSTLIT>key|...| </@>
|
||||
<@ LETVARAFTVALLSTLIT>val|...| </@>
|
||||
<@ OMT> test for an empty key (in the case of a boolean) </@>
|
||||
<@ TSTVARLIT>key|</@>
|
||||
<@ IFE><@ LETPNTVARVARLIT>val|__True</@></@>
|
||||
<@ ELS>
|
||||
<@ TSTGT0ATBVARLIT>val|,</@>
|
||||
<@ IFE><@ ACTEXEEMMCAP><&prot; LETCNDLSTLITLIT>&key;&pipe;&val;&pipe;, </&prot;></@></@>
|
||||
<@ ELS><@ LETPNTVARVARVAR>key|val</@></@>
|
||||
</@>
|
||||
</@>
|
||||
</@>
|
||||
|
||||
<@ ACTUDRLIT>__ReadConfigurationFile|c:\rosetta.config</@>
|
||||
<@ SAYVAR>FAVOURITEFRUIT</@>
|
||||
<@ SAYVAR>FULLNAME</@>
|
||||
<@ SAYVAR>NEEDSPEELING</@>
|
||||
<@ SAYDMPLST>OTHERFAMILY</@>
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/*REXX program to read a config file and assign VARs as found within. */
|
||||
signal on syntax; signal on novalue /*handle REXX program errors. */
|
||||
parse arg cFID _ . /*cFID = config file to be read. */
|
||||
if cFID=='' then cFID='CONFIG.DAT' /*Not specified? Use the default*/
|
||||
bad= /*this will contain all bad VARs.*/
|
||||
varList= /*this will contain all the VARs.*/
|
||||
maxLenV=0; blanks=0; hashes=0; semics=0; badVar=0 /*zero 'em.*/
|
||||
|
||||
do j=0 while lines(cFID)\==0 /*J count's the file's lines. */
|
||||
txt=strip(linein(cFID)) /*read a line (record) from file,*/
|
||||
/*& strip leading/trailing blanks*/
|
||||
if txt ='' then do; blanks=blanks+1; iterate; end
|
||||
if left(txt,1)=='#' then do; hashes=hashes+1; iterate; end
|
||||
if left(txt,1)==';' then do; semics=semics+1; iterate; end
|
||||
eqS=pos('=',txt) /*can't use the TRANSLATE bif. */
|
||||
if eqS\==0 then txt=overlay(' ',txt,eqS) /*replace 1st '=' with blank*/
|
||||
parse var txt xxx value; upper xxx /*get the variableName and value.*/
|
||||
value=strip(value) /*strip leading & trailing blanks*/
|
||||
varList=varList xxx /*add it to the list of vARiables*/
|
||||
if value='' then value='true' /*if no value, then use "true". */
|
||||
if symbol(xxx)=='BAD' then do /*can REXX use the variable name?*/
|
||||
badVar=badVar+1; bad=bad xxx; iterate
|
||||
end
|
||||
call value xxx,value /*now, use VALUE to set the var. */
|
||||
maxLenV=max(maxLenV,length(value)) /*maxLen of varNames, pretty disp*/
|
||||
end /*j*/
|
||||
|
||||
vars=words(varList)
|
||||
say #(j) 'record's(j) "were read from file: " cFID
|
||||
if blanks\==0 then say #(blanks) 'blank record's(blanks) "were read."
|
||||
if hashes\==0 then say #(hashes) 'record's(hashes) "ignored that began with a # (hash)."
|
||||
if semics\==0 then say #(semics) 'record's(semics) "ignored that began with a ; (semicolon)."
|
||||
if badVar\==0 then say #(badVar) 'bad variable name's(badVar) 'detected:' bad
|
||||
say; say 'The list of' vars "variable"s(vars) 'and' s(vars,'their',"it's") "value"s(vars) 'follows:'; say
|
||||
|
||||
do k=1 for vars
|
||||
v=word(varList,k)
|
||||
say right(v,maxLenV) '=' value(v)
|
||||
end /*k*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*───────────────────────────────error handling subroutines and others.─*/
|
||||
s: if arg(1)==1 then return arg(3); return word(arg(2) 's',1)
|
||||
#: return right(arg(1),length(j)+11) /*right justify a number +indent*/
|
||||
err: say; say; say center(' error! ', max(40, linesize()%2), "*"); say
|
||||
do j=1 for arg(); say arg(j); say; end; say; exit 13
|
||||
novalue: syntax: call err 'REXX program' condition('C') "error",,
|
||||
condition('D'),'REXX source statement (line' sigl"):",sourceline(sigl)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
fcn readConfigFile(config){ //--> read only dictionary
|
||||
conf:=Dictionary();
|
||||
foreach line in (config){
|
||||
line=line.strip();
|
||||
if (not line or "#"==line[0] or ";"==line[0]) continue;
|
||||
line=line.replace("\t"," ");
|
||||
n:=line.find(" ");
|
||||
if (Void==n) conf[line.toLower()]=True; // eg NEEDSPEELING
|
||||
else{
|
||||
key:=line[0,n].toLower(); line=line[n,*];
|
||||
n=line.find(",");
|
||||
if (Void!=n) conf[key]=line.split(",").apply("strip").filter();
|
||||
else conf[key]=line;
|
||||
}
|
||||
}
|
||||
conf.makeReadOnly();
|
||||
}
|
||||
|
||||
conf:=readConfigFile(File("foo.conf"));
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
foreach k,v in (conf){ println(k," : ",v) }
|
||||
println("Value of seedsremoved = ",conf.find("seedsremoved",False));
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
var needspeeling,otherfamily,favouritefruit,fullname,seedsremoved;
|
||||
foreach k,v in (conf){ try{ setVar(k,v) }catch{} };
|
||||
foreach k,v in (vars){ println(k," : ",v) }
|
||||
println("Value of seedsremoved = ",seedsremoved);
|
||||
Loading…
Add table
Add a link
Reference in a new issue