Read a configuration file: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|D}}: change to regexp version)
Line 30: Line 30:


=={{header|D}}==
=={{header|D}}==
<lang d>import std.stdio, std.getopt, std.string, std.conv, std.regexp ;
A version to abusing module [http://www.digitalmars.com/d/2.0/phobos/std_getopt.html std.getopt].
<lang d>import std.stdio, std.getopt, std.string, std.conv ;


template VarName(alias Var) { enum VarName = Var.stringof.toupper ; }
template VarName(alias Var) { enum VarName = Var.stringof.toupper ; }

void setOpt(alias Var)(const string line) {
auto m = RegExp(`^`~VarName!Var~`(\s+(.*))?`).match(line) ;
if(m.length > 0) {
static if (is(typeof(Var) == string))
Var = m.length > 2 ? m[2] : "" ;
static if (is(typeof(Var) == bool))
Var = true ;
static if (is(typeof(Var) == int))
Var = m.length > 2 ? to!int(m[2]) : 0 ;
}
}


void main(string[] args) {
void main(string[] args) {
Line 40: Line 51:
int count ; // a line of "COUNT 5" added at end of config file
int count ; // a line of "COUNT 5" added at end of config file
foreach(line ; File("readcfg.txt").byLine) {
foreach(line ; File("readcfg.txt").byLine) {
auto opt = ("--" ~ text(chomp(line))).split(" ") ;
auto opt = chomp(text(line)) ;
setOpt!fullname(opt) ;
opt = (["program name dummy"] ~ opt[0]) ~ opt[1..$].join(" ") ;
getopt( opt ,
setOpt!favouritefruit(opt) ;
setOpt!needspeeling(opt) ;
std.getopt.config.passThrough, // ignore unknown option
setOpt!seedsremoved(opt) ;
std.getopt.config.caseSensitive,
setOpt!count(opt) ;
"FULLNAME", &fullname,
"FAVOURITEFRUIT", &favouritefruit,
"NEEDSPEELING", &needspeeling ,
"SEEDSREMOVED", &seedsremoved,
"COUNT", &count) ;
}
}
writefln("%14s = %s", VarName!fullname, fullname) ;
writefln("%14s = %s", VarName!fullname, fullname) ;
Line 57: Line 64:
writefln("%14s = %s", VarName!count, count) ;
writefln("%14s = %s", VarName!count, count) ;
}</lang>
}</lang>

=={{header|J}}==
=={{header|J}}==



Revision as of 00:00, 17 February 2011

Read a configuration file is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

The task is to read a configuration file in standard configuration file, and set variables accordingly. For this task, we have a configuration file as follows:

# This is a configuration file in standard configuration file format
#
# Lines that begin with a hash symbol or semicolon are treated as
# comments and will be ignored

# This is the fullname parameter
FULLNAME Foo Barber

# This is a favourite fruit
FAVOURITEFRUIT banana

# This is a boolean that should be set
NEEDSPEELING

# This boolean is commented out
; SEEDSREMOVED


For the task we need to set four variables according to the configuration entries as follows:

  • fullname = Foo Barber
  • favouritefruit = banana
  • needspeeling = true
  • seedsremoved = false


D

<lang d>import std.stdio, std.getopt, std.string, std.conv, std.regexp ;

template VarName(alias Var) { enum VarName = Var.stringof.toupper ; }

void setOpt(alias Var)(const string line) {

   auto m = RegExp(`^`~VarName!Var~`(\s+(.*))?`).match(line) ;
   if(m.length > 0) {
       static if (is(typeof(Var) == string))
           Var = m.length > 2 ? m[2] : "" ;
       static if (is(typeof(Var) == bool))
           Var = true ;
       static if (is(typeof(Var) == int))
           Var = m.length > 2 ? to!int(m[2]) : 0 ;
   }

}

void main(string[] args) {

   string fullname, favouritefruit ;
   bool needspeeling, seedsremoved ; // default false ;
   int count ; // a line of "COUNT 5" added at end of config file
   foreach(line ; File("readcfg.txt").byLine) {
       auto opt = chomp(text(line)) ;
       setOpt!fullname(opt) ;
       setOpt!favouritefruit(opt) ;
       setOpt!needspeeling(opt) ;
       setOpt!seedsremoved(opt) ;
       setOpt!count(opt) ;
   }
   writefln("%14s = %s", VarName!fullname, fullname) ;
   writefln("%14s = %s", VarName!favouritefruit, favouritefruit) ;
   writefln("%14s = %s", VarName!needspeeling, needspeeling) ;
   writefln("%14s = %s", VarName!seedsremoved, seedsremoved) ;
   writefln("%14s = %s", VarName!count, count) ;

}</lang>

J

<lang j>require'regex' set=:4 :'(x)=:y'

cfgString=:4 :0

 y set 
 (1;&,~'(?i:',y,')\s*(.*)') y&set rxapply x

)

cfgBoolean=:4 :0

 y set 0
 (1;&,~'(?i:',y,')\s*(.*)') y&set rxapply x
 if.-.0-:y do.y set 1 end.

)

taskCfg=:3 :0

 cfg=: ('[#;].*';) rxrplc 1!:1<y
 cfg cfgString 'fullname'
 cfg cfgString 'favouritefruit'
 cfg cfgBoolean 'needspeeling'
 cfg cfgBoolean 'seedsremoved'
 i.0 0

)</lang>

Example use:

<lang j> taskCfg 'fruit.conf'

  (,' = ',]&.do)&>;: 'fullname favouritefruit needspeeling seedsremoved'

fullname = Foo Barber favouritefruit = banana needspeeling = 1 seedsremoved = 0 </lang>

Ruby

<lang ruby>fullname = favouritefruit = needspeeling = seedsremoved = false

open("fruit.conf", "r") do |file|

 file.each_line do |line|
   line.chomp!
   key, value = line.split(nil, 2)
   case key
   when /^([#;]|$)/; # ignore line
   when "FULLNAME"; fullname = value
   when "FAVOURITEFRUIT"; favouritefruit = value
   when "NEEDSPEELING"; needspeeling = true
   when "SEEDSREMOVED"; seedsremoved = true
   when /^./; puts "#{key}: unknown key"
   end
 end

end

puts "fullname = #{fullname}" puts "favouritefruit = #{favouritefruit}" puts "needspeeling = #{needspeeling}" puts "seedsremoved = #{seedsremoved}"</lang>