Skip to content
Snippets Groups Projects
Commit 6aa4d3ee authored by Andrea Censi's avatar Andrea Censi
Browse files

Improved and aligned with ruby version

parent ddde6d6e
No related branches found
No related tags found
No related merge requests found
......@@ -27,6 +27,12 @@
#include "options.h"
const char * options_banner_string = "";
void options_banner(const char*message) {
options_banner_string = message;
}
/** Our version of strdup. */
char * strdup_(const char *s) {
size_t len = strlen(s) + 1; /* null byte */
......@@ -85,7 +91,7 @@ int options_parse_args(struct option*ops, int argc, const char* argv[]) {
struct option * o;
if(0 == (o =options_find(ops, name)) ) {
fprintf(stderr, "Option '%s' not found.\n", name);
fprintf(stderr, "Option '%s' not found (use -help to get list of options).\n", name);
if(!options_tolerant) return 0;
}
......@@ -136,12 +142,23 @@ int options_parse_stream(struct option*ops, const char*pwd, FILE*file) {
continue;
}
if(!*line) continue;
/* Here starts the name; later we put a terminating 0 */
const char * name = line;
/* name continus until nonspace char */
while(!isspace(*line)) line++;
char * value;
if(*line == 0) value = ""; else {
*line = 0; line++;
*line = 0; /* terminating 0 for name */
line++;
/* ignore spaces */
while(isspace(*line)) line++;
/* ignore possible "=" */
if(*line == '=') line++;
/* ignore spaces */
while(isspace(*line)) line++;
/* here starts the value */
value = line;
/* delete final spaces */
int len = strlen(value);
......@@ -318,6 +335,7 @@ void options_dump(struct option * options, FILE*f, int write_desc) {
}
void options_print_help(struct option * options, FILE*f) {
fprintf(f, options_banner_string);
fprintf(f,
"Generic options: \n"
" -help Displays this help.\n"
......
......@@ -44,6 +44,10 @@ struct option {
/** User-friendly interface */
/* Sets the banner for the help message. (pointer is kept) */
void options_banner(const char*message);
struct option* options_allocate(int n);
void options_int (struct option*, const char* name,
......
......@@ -11,6 +11,8 @@
#include "options.h"
/** User-friendly interface */
struct option* options_allocate(int n) {
n += 2; /* better safe than sorry */
struct option* ops = malloc(sizeof(struct option)*n);
......
require 'ostruct'
require 'optparse'
class Options
Option = Struct.new(:name, :default, :description, :value)
def initialize
@hash = {}
@order = []
end
def add(name, default, description)
if name.class == String
name = name.to_sym
end
if name.class != Symbol
raise "This: #{name.inspect} should be a String or Symbol"
end
@hash[name] = Option.new(name, default, description, nil)
@order.push @hash[name]
end
def add_required(name, description)
add(name, nil, description)
end
def populate(opts)
opts.on("--help", "shows help") do
$stderr.puts opts.help
exit 0
end
opts.on("--config FILE", "Load config from file") do |file|
load_config_from_file(file)
end
opts.on("--config_dump", "Dump config on stdout") do
$stdout.puts self.config_dump
exit 0
end
@order.each do |o|
s = o.default.inspect.ljust(25)
opts.on("--#{o.name} VALUE", "#{s} #{o.description}") do |s|
value = s
begin value = eval(s)
rescue SyntaxError => ex
rescue => ex
end
@hash[o.name].value = value
end
end
end
# Create an ostruct from the data
def get_ostruct
r = {}
@hash.each do |k, v|
r[k] = v.value || v.default
end
OpenStruct.new r
end
# Warn if some required parameter was not set
# (default and value are nil)
def warn_required
res = false
@order.each do |v|
if v.value.nil? && v.default.nil?
$stderr.puts "Required option '#{v.name}' not set."
res = true
end
end
res
end
def config_dump
s = ""
max_size = @hash.keys.map{|x|x.to_s.size}.max + 2
for o in @order
s += o.name.to_s.ljust(max_size) + (o.value || o.default).inspect + "\n"
end
s
end
RegComment = /^\s*\#/
RegOption = /^\s*(\w+)\s*=?\s*(.+)$/
RegLoad = /^\s*(?:<|source)\s*(.*)$/
def load_config_from_file(file)
load_config_from_string(File.open(file).read, File.dirname(file))
end
def load_config_from_string(string, dir)
string.split("\n").each do |line|
next if (line.strip.size == 0) || line =~ RegComment
if m = RegLoad.match(line)
filename = m[1]
filename = File.expand_path(File.join(dir, filename))
load_config_from_file(filename)
elsif m = RegOption.match(line)
name = m[1].to_sym
value = m[2].strip
begin
value = eval(value)
rescue ScriptError,StandardError
end
if o = @hash[name]
o.value = value
# $stderr.puts "#{name} = #{value}"
else
$stderr.puts "Unknown key #{name.inspect} (#{@hash.keys.inspect})"
end
else
$stderr.puts "Line #{line.inspect} is malformed"
exit -1
end
end
end
def parse_cmd_line!
opt = OptionParser.new do |opts|
self.populate(opts)
end
begin opt.parse!
rescue OptionParser::InvalidOption=>e
$stderr.puts e
$stderr.puts opt
exit -1
end
end
end
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment