ctioga2 0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +339 -0
- data/Changelog +6 -0
- data/bin/ctioga2 +26 -0
- data/lib/ctioga2/commands/arguments.rb +58 -0
- data/lib/ctioga2/commands/commands.rb +258 -0
- data/lib/ctioga2/commands/doc/doc.rb +118 -0
- data/lib/ctioga2/commands/doc/documentation-commands.rb +119 -0
- data/lib/ctioga2/commands/doc/help.rb +95 -0
- data/lib/ctioga2/commands/doc/html.rb +230 -0
- data/lib/ctioga2/commands/doc/introspection.rb +211 -0
- data/lib/ctioga2/commands/doc/man.rb +279 -0
- data/lib/ctioga2/commands/doc/markup.rb +359 -0
- data/lib/ctioga2/commands/general-commands.rb +119 -0
- data/lib/ctioga2/commands/general-types.rb +118 -0
- data/lib/ctioga2/commands/groups.rb +73 -0
- data/lib/ctioga2/commands/interpreter.rb +257 -0
- data/lib/ctioga2/commands/parsers/command-line.rb +187 -0
- data/lib/ctioga2/commands/parsers/file.rb +186 -0
- data/lib/ctioga2/commands/strings.rb +303 -0
- data/lib/ctioga2/commands/type.rb +100 -0
- data/lib/ctioga2/commands/variables.rb +101 -0
- data/lib/ctioga2/data/backends/backend.rb +260 -0
- data/lib/ctioga2/data/backends/backends.rb +39 -0
- data/lib/ctioga2/data/backends/backends/gnuplot.rb +140 -0
- data/lib/ctioga2/data/backends/backends/math.rb +121 -0
- data/lib/ctioga2/data/backends/backends/text.rb +335 -0
- data/lib/ctioga2/data/backends/description.rb +405 -0
- data/lib/ctioga2/data/backends/factory.rb +73 -0
- data/lib/ctioga2/data/backends/parameter.rb +109 -0
- data/lib/ctioga2/data/datacolumn.rb +245 -0
- data/lib/ctioga2/data/dataset.rb +233 -0
- data/lib/ctioga2/data/filters.rb +131 -0
- data/lib/ctioga2/data/merge.rb +43 -0
- data/lib/ctioga2/data/point.rb +72 -0
- data/lib/ctioga2/data/stack.rb +294 -0
- data/lib/ctioga2/graphics/coordinates.rb +73 -0
- data/lib/ctioga2/graphics/elements.rb +111 -0
- data/lib/ctioga2/graphics/elements/containers.rb +111 -0
- data/lib/ctioga2/graphics/elements/curve2d.rb +155 -0
- data/lib/ctioga2/graphics/elements/element.rb +90 -0
- data/lib/ctioga2/graphics/elements/primitive.rb +256 -0
- data/lib/ctioga2/graphics/elements/subplot.rb +140 -0
- data/lib/ctioga2/graphics/generator.rb +68 -0
- data/lib/ctioga2/graphics/legends.rb +108 -0
- data/lib/ctioga2/graphics/legends/area.rb +199 -0
- data/lib/ctioga2/graphics/legends/items.rb +183 -0
- data/lib/ctioga2/graphics/legends/provider.rb +58 -0
- data/lib/ctioga2/graphics/legends/storage.rb +65 -0
- data/lib/ctioga2/graphics/root.rb +209 -0
- data/lib/ctioga2/graphics/styles.rb +30 -0
- data/lib/ctioga2/graphics/styles/axes.rb +247 -0
- data/lib/ctioga2/graphics/styles/background.rb +122 -0
- data/lib/ctioga2/graphics/styles/base.rb +115 -0
- data/lib/ctioga2/graphics/styles/carrays.rb +53 -0
- data/lib/ctioga2/graphics/styles/curve.rb +101 -0
- data/lib/ctioga2/graphics/styles/drawable.rb +87 -0
- data/lib/ctioga2/graphics/styles/factory.rb +351 -0
- data/lib/ctioga2/graphics/styles/legend.rb +63 -0
- data/lib/ctioga2/graphics/styles/plot.rb +410 -0
- data/lib/ctioga2/graphics/styles/sets.rb +64 -0
- data/lib/ctioga2/graphics/styles/texts.rb +277 -0
- data/lib/ctioga2/graphics/subplot-commands.rb +141 -0
- data/lib/ctioga2/graphics/types.rb +188 -0
- data/lib/ctioga2/graphics/types/bijection.rb +79 -0
- data/lib/ctioga2/graphics/types/boundaries.rb +170 -0
- data/lib/ctioga2/graphics/types/boxes.rb +157 -0
- data/lib/ctioga2/graphics/types/dimensions.rb +157 -0
- data/lib/ctioga2/graphics/types/point.rb +247 -0
- data/lib/ctioga2/log.rb +97 -0
- data/lib/ctioga2/metabuilder/type.rb +316 -0
- data/lib/ctioga2/metabuilder/types.rb +39 -0
- data/lib/ctioga2/metabuilder/types/coordinates.rb +124 -0
- data/lib/ctioga2/metabuilder/types/dates.rb +43 -0
- data/lib/ctioga2/metabuilder/types/lists.rb +188 -0
- data/lib/ctioga2/metabuilder/types/numbers.rb +97 -0
- data/lib/ctioga2/metabuilder/types/strings.rb +93 -0
- data/lib/ctioga2/metabuilder/types/styles.rb +178 -0
- data/lib/ctioga2/plotmaker.rb +677 -0
- data/lib/ctioga2/postprocess.rb +115 -0
- data/lib/ctioga2/utils.rb +120 -0
- data/setup.rb +1586 -0
- metadata +144 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# type.rb: named types, based on metabuilder
|
|
2
|
+
# copyright (c) 2009 by Vincent Fourmond
|
|
3
|
+
|
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details (in the COPYING file).
|
|
13
|
+
|
|
14
|
+
require 'ctioga2/utils'
|
|
15
|
+
require 'ctioga2/metabuilder/types'
|
|
16
|
+
|
|
17
|
+
module CTioga2
|
|
18
|
+
|
|
19
|
+
Version::register_svn_info('$Revision: 18 $', '$Date: 2009-04-28 23:43:54 +0200 (Tue, 28 Apr 2009) $')
|
|
20
|
+
|
|
21
|
+
module Commands
|
|
22
|
+
|
|
23
|
+
# A named type, based on CTioga2::MetaBuilder::Type
|
|
24
|
+
class CommandType
|
|
25
|
+
|
|
26
|
+
# The underlying CTioga2::MetaBuilder::Type object.
|
|
27
|
+
attr_accessor :type
|
|
28
|
+
|
|
29
|
+
# The unique identification of this type.
|
|
30
|
+
attr_accessor :name
|
|
31
|
+
|
|
32
|
+
# The description of this type
|
|
33
|
+
attr_accessor :description
|
|
34
|
+
|
|
35
|
+
# The context of definition [file, line]
|
|
36
|
+
attr_accessor :context
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Makes sure the return value is a CommandType. Will fail
|
|
40
|
+
# miserably if not.
|
|
41
|
+
def self.get_type(obj)
|
|
42
|
+
if obj.is_a? CommandType
|
|
43
|
+
return obj
|
|
44
|
+
else
|
|
45
|
+
if obj.is_a? Symbol
|
|
46
|
+
warn "Converting type specifcation #{obj.inspect} to string at #{caller[1]}"
|
|
47
|
+
obj = obj.to_s
|
|
48
|
+
end
|
|
49
|
+
type = Interpreter::type(obj)
|
|
50
|
+
if type
|
|
51
|
+
return type
|
|
52
|
+
else
|
|
53
|
+
raise InvalidType, "Type #{obj.inspect} unknown"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# _type_ is the type of the argument in a descriptive fashion,
|
|
59
|
+
# as could be fed to CTioga2::MetaBuilder::Type.get_type, or
|
|
60
|
+
# directly a MetaBuilder::Type object.
|
|
61
|
+
def initialize(name, type, desc = nil)
|
|
62
|
+
if type.is_a? MetaBuilder::Type
|
|
63
|
+
@type = type
|
|
64
|
+
else
|
|
65
|
+
@type = CTioga2::MetaBuilder::Type.get_type(type)
|
|
66
|
+
end
|
|
67
|
+
@name = name
|
|
68
|
+
@description = desc
|
|
69
|
+
caller[1].gsub(/.*\/ctioga2\//, 'lib/ctioga2/') =~ /(.*):(\d+)/
|
|
70
|
+
@context = [$1, $2.to_i]
|
|
71
|
+
|
|
72
|
+
Interpreter::register_type(self)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Now, a series of redirection from/to the underlying
|
|
76
|
+
# MetaBuilder::Type object.
|
|
77
|
+
|
|
78
|
+
# Whether this is a boolean type or not.
|
|
79
|
+
def boolean?
|
|
80
|
+
return @type.boolean?
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Does the actual conversion from string to the real type
|
|
84
|
+
def string_to_type(str)
|
|
85
|
+
return @type.string_to_type(str)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Returns the long option for the option parser.
|
|
89
|
+
#
|
|
90
|
+
# TODO: maybe this should be rethought a bit ?
|
|
91
|
+
def option_parser_long_option(name, param = nil)
|
|
92
|
+
return @type.option_parser_long_option(name, param)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# variables.rb: the variable system for the commands
|
|
2
|
+
# copyright (c) 2009 by Vincent Fourmond
|
|
3
|
+
|
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details (in the COPYING file).
|
|
13
|
+
|
|
14
|
+
require 'ctioga2/utils'
|
|
15
|
+
require 'ctioga2/commands/strings'
|
|
16
|
+
|
|
17
|
+
module CTioga2
|
|
18
|
+
|
|
19
|
+
Version::register_svn_info('$Revision: 2 $', '$Date: 2009-04-25 14:03:30 +0200 (Sat, 25 Apr 2009) $')
|
|
20
|
+
|
|
21
|
+
module Commands
|
|
22
|
+
|
|
23
|
+
class RecursiveExpansion < Exception
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# A holder for variables. Variables in ctioga2 are very similar to
|
|
27
|
+
# the ones found in make(1).
|
|
28
|
+
# They are only pieces of text that are expanded using the
|
|
29
|
+
# $(variable)
|
|
30
|
+
# syntax, just like in make.
|
|
31
|
+
#
|
|
32
|
+
# There are two kind of variables
|
|
33
|
+
# * immediate, defined by
|
|
34
|
+
# variable := value
|
|
35
|
+
# or
|
|
36
|
+
# These ones are evaluated for once when they are defined.
|
|
37
|
+
# They are stored in the form of a String
|
|
38
|
+
# * recursively expanded variables. They are mostly like immediate
|
|
39
|
+
# variables, excepted that the values of the replacement texts
|
|
40
|
+
# for variables used within are expanded at the moment the
|
|
41
|
+
# variable is expanded, and not at the moment of its definition
|
|
42
|
+
# as before. They are defined by
|
|
43
|
+
# variable = value
|
|
44
|
+
# They are stored in the form on an InterpreterString
|
|
45
|
+
#
|
|
46
|
+
# TODO: The variables system should automatically transform
|
|
47
|
+
# recursive variables into immediate ones when there is no
|
|
48
|
+
# variables replacement text.
|
|
49
|
+
class Variables
|
|
50
|
+
|
|
51
|
+
# A hash "variable name" => String or InterpreterString
|
|
52
|
+
attr_accessor :variables
|
|
53
|
+
|
|
54
|
+
# Creates a new empty Variables object
|
|
55
|
+
def initialize
|
|
56
|
+
@variables = {}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Sets a the variable _name_ to _value_ (being an
|
|
60
|
+
# InterpreterString or a String). If _interpreter_ is given, the
|
|
61
|
+
# value is expanded at the time of the definition, (immediate
|
|
62
|
+
# variable), whereas if it stays _nil_, the variable is defined
|
|
63
|
+
# as a recursively defined variable.
|
|
64
|
+
def define_variable(name, value, interpreter = nil)
|
|
65
|
+
if value.respond_to? :expand_to_string
|
|
66
|
+
if interpreter
|
|
67
|
+
value = value.expand_to_string(interpreter)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
@variables[name] = value
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Fully expands a variable. Returns a String. _name_ is the
|
|
74
|
+
# name of the variable, and _interpreter_ the context in which
|
|
75
|
+
# the expansion will take place.
|
|
76
|
+
#
|
|
77
|
+
# *Note* it is assumed here that the variables live in the
|
|
78
|
+
# _interpreter_.
|
|
79
|
+
def expand_variable(name, interpreter)
|
|
80
|
+
if @variables.key? name
|
|
81
|
+
var = @variables[name]
|
|
82
|
+
if var.respond_to? :expand_to_string
|
|
83
|
+
begin
|
|
84
|
+
return var.expand_to_string(interpreter)
|
|
85
|
+
rescue SystemStackError
|
|
86
|
+
raise RecursiveExpansion, "The stack smashed while expanding variable #{name}. This probably means it is a recursive variable referring to itself. Use := in the definition to avoid that"
|
|
87
|
+
end
|
|
88
|
+
else
|
|
89
|
+
return var
|
|
90
|
+
end
|
|
91
|
+
else
|
|
92
|
+
return ""
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
101
|
+
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# backend.rb : The base of the arcitecture of the Backends
|
|
2
|
+
# Copyright (C) 2006, 2009 Vincent Fourmond
|
|
3
|
+
|
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program; if not, write to the Free Software
|
|
16
|
+
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
require 'ctioga2/utils'
|
|
20
|
+
require 'ctioga2/data/backends/description'
|
|
21
|
+
|
|
22
|
+
module CTioga2
|
|
23
|
+
|
|
24
|
+
Version::register_svn_info('$Revision: 59 $', '$Date: 2009-05-28 23:15:50 +0200 (Thu, 28 May 2009) $')
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
module Data
|
|
28
|
+
|
|
29
|
+
# The Backends are in charge of acquiring DataSet from various
|
|
30
|
+
# data sources.
|
|
31
|
+
module Backends
|
|
32
|
+
|
|
33
|
+
# This class provides the infrastructure for accessing data sets. It
|
|
34
|
+
# shouldn't be used directly, but rather subclassed and reimplemented.
|
|
35
|
+
# The aim of this class is to provide any software which is interested
|
|
36
|
+
# to retrive data from some source with a consistent way to do so,
|
|
37
|
+
# independent the kind of source accessed.
|
|
38
|
+
#
|
|
39
|
+
# TODO: update documentation.
|
|
40
|
+
#
|
|
41
|
+
# Subclasses should:
|
|
42
|
+
# * provide a consistent method for creating themselves,
|
|
43
|
+
# with as much information as necessary, including options and default
|
|
44
|
+
# parameters. Actually, their initialize function should take no value
|
|
45
|
+
# but on the other side, the BackendDescription associated with it
|
|
46
|
+
# should make it easy to set all the parameters necessary to
|
|
47
|
+
# get one set of data.
|
|
48
|
+
# * provide a way to fill an OptionParser with their own parameters
|
|
49
|
+
# * provide a way to retrieve the data via named 'sets' (either 2D or 3D
|
|
50
|
+
# data, depending on the subclass)
|
|
51
|
+
# * provide a way to obtain all meta-informations on one dataset,
|
|
52
|
+
# such as the date, the meaning of the columns (if any), and so on.
|
|
53
|
+
# * provide a way to know which named sets are available, or at least
|
|
54
|
+
# a subset (or nothing if we don't know a thing).
|
|
55
|
+
# * wether the actual reading of the data is done at initialization time
|
|
56
|
+
# or at query time is left to the implementor ;-) !
|
|
57
|
+
#
|
|
58
|
+
# TODO: adapt to the new structure.
|
|
59
|
+
#
|
|
60
|
+
# TODO: add back filters (with time)
|
|
61
|
+
#
|
|
62
|
+
# TODO: add a Cache ?
|
|
63
|
+
class Backend
|
|
64
|
+
|
|
65
|
+
# Include logging facilities...
|
|
66
|
+
include CTioga2::Log
|
|
67
|
+
|
|
68
|
+
# Import the main description functions into the appropriate
|
|
69
|
+
# namespaces
|
|
70
|
+
extend BackendDescriptionExtend
|
|
71
|
+
|
|
72
|
+
# Backend is a factory, but no autoregistering is made.
|
|
73
|
+
create_factory false
|
|
74
|
+
|
|
75
|
+
# Sets up a few things, such as the filters.
|
|
76
|
+
def initialize
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Returns the BackendDescription associated with this Backend.
|
|
80
|
+
def description
|
|
81
|
+
return self.class.description
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Creates a description object with the given texts and
|
|
85
|
+
# associates it with the class. It is necessary to have this
|
|
86
|
+
# statement *before* any parameter declaration. If you don't
|
|
87
|
+
# set any description, you will not be able to benefit from
|
|
88
|
+
# the plugin system. To be used in Backend subclasses, simply
|
|
89
|
+
# this way:
|
|
90
|
+
#
|
|
91
|
+
# describe "biniou", "Biniou backend", "A backend to deal with Binious"
|
|
92
|
+
#
|
|
93
|
+
def Backend.describe(name, longname, desc, register = true)
|
|
94
|
+
d = BackendDescription.new(self, name, longname, desc, register)
|
|
95
|
+
set_description(d)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Returns a hash containing the description of all available
|
|
99
|
+
# backends
|
|
100
|
+
def Backend.list_backends
|
|
101
|
+
return factory_description_hash
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
describe 'backend', 'The base class for backends', <<EOD, false
|
|
105
|
+
This is the base class for backends. It should never be used directly.
|
|
106
|
+
EOD
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
# TODO: the baseline should not be implemented.
|
|
110
|
+
# It is much more efficient to ;
|
|
111
|
+
# * implement a dataset subtraction command;
|
|
112
|
+
# * use the add-dataset hook to automatically subtract a given
|
|
113
|
+
# (named ?) buffer.
|
|
114
|
+
|
|
115
|
+
# A hook to set a baseline:
|
|
116
|
+
# param_reader :base_line=, :base_line, "baseline", "Base line",
|
|
117
|
+
# {:type => :string, }, "Sets a baseline for subsequent data sets"
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# Returns true if the backend can provide data for the given set.
|
|
121
|
+
def has_set?(set)
|
|
122
|
+
return false
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
alias set? has_set?
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
# Public interface to query DataSet from a Backend. Children
|
|
129
|
+
# must redefine #query_dataset rather than this function. This
|
|
130
|
+
# function also applies filters and does othe kinds of
|
|
131
|
+
# transformations
|
|
132
|
+
def dataset(set)
|
|
133
|
+
return query_dataset(set)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# When converting a user input into a set, a program should
|
|
138
|
+
# *always* use this function, unless it has really good
|
|
139
|
+
# reasons for that.
|
|
140
|
+
#
|
|
141
|
+
# The default implementation is to expand 2##4 to 2, 3, 4. Can
|
|
142
|
+
# be useful even for mathematical stuff.
|
|
143
|
+
#
|
|
144
|
+
# Another thing is recognised and expanded: #<2<i*2>,5> runs
|
|
145
|
+
# the code i*2 with the values from 2 to 5 and returns the
|
|
146
|
+
# result. The code in the middle is a Ruby block, and
|
|
147
|
+
# therefore should be valid !
|
|
148
|
+
#
|
|
149
|
+
# A third expansion is now available: #<a = 2<a * sin(x)>10>
|
|
150
|
+
# will expand into 2*sin(x) , 3*sin(x) ... 10*sin(x) it is
|
|
151
|
+
# different than the previous in the sense that the code in
|
|
152
|
+
# the middle is not a Ruby code, but a mere string, which
|
|
153
|
+
# means there won't be compilation problems.
|
|
154
|
+
#
|
|
155
|
+
# Unless your backend can't accomodate for that, all
|
|
156
|
+
# redefinitions of this function should check for their
|
|
157
|
+
# specific signatures first and call this function if they
|
|
158
|
+
# fail. This way, they will profit from improvements in this
|
|
159
|
+
# code while keeping old stuff working.
|
|
160
|
+
def expand_sets(spec)
|
|
161
|
+
if m = /(\d+)##(\d+)/.match(spec)
|
|
162
|
+
debug "Using expansion rule #1"
|
|
163
|
+
a = m[1].to_i
|
|
164
|
+
b = m[2].to_i
|
|
165
|
+
ret = []
|
|
166
|
+
a.upto(b) do |i|
|
|
167
|
+
ret << m.pre_match + i.to_s + m.post_match
|
|
168
|
+
end
|
|
169
|
+
return ret
|
|
170
|
+
elsif m = /\#<(\d+)<(.*?)>(\d+)>/.match(spec)
|
|
171
|
+
debug "Using expansion rule #2"
|
|
172
|
+
from = m[1].to_i
|
|
173
|
+
to = m[3].to_i
|
|
174
|
+
debug "Ruby code used for expansion: {|i| #{m[2]} }"
|
|
175
|
+
code = eval "proc {|i| #{m[2]} }"
|
|
176
|
+
ret = []
|
|
177
|
+
from.upto(to) do |i|
|
|
178
|
+
ret << m.pre_match + code.call(i).to_s + m.post_match
|
|
179
|
+
end
|
|
180
|
+
return ret
|
|
181
|
+
elsif m = /\#<\s*(\w+)\s*=\s*(\d+)\s*<(.*?)>\s*(\d+)\s*>/.match(spec)
|
|
182
|
+
debug "Using expansion rule #3"
|
|
183
|
+
var = m[1]
|
|
184
|
+
from = m[2].to_i
|
|
185
|
+
to = m[4].to_i
|
|
186
|
+
# Then we replace all occurences of the variable
|
|
187
|
+
literal = '"' + m[3].gsub(/\b#{var}\b/, '#{' + var + '}') + '"'
|
|
188
|
+
debug "Ruby code used for expansion: {|#{var}| #{literal} }"
|
|
189
|
+
code = eval "proc {|#{var}| #{literal} }"
|
|
190
|
+
ret = []
|
|
191
|
+
from.upto(to) do |i|
|
|
192
|
+
ret << m.pre_match + code.call(i).to_s + m.post_match
|
|
193
|
+
end
|
|
194
|
+
return ret
|
|
195
|
+
end
|
|
196
|
+
# Fallback
|
|
197
|
+
return [spec]
|
|
198
|
+
rescue Exception => ex
|
|
199
|
+
# In case something went wrong in the eval.
|
|
200
|
+
warn "An error occured during expansion of '#{spec}': #{ex.message}"
|
|
201
|
+
debug "Error backtrace: #{ex.backtrace.join "\n"}"
|
|
202
|
+
warn "Ignoring, but you're nearly garanteed something will "+
|
|
203
|
+
"fail later on"
|
|
204
|
+
return [spec]
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Some backends have a pretty good idea of the sets available
|
|
208
|
+
# for use. Some really don't. You can choose to reimplement
|
|
209
|
+
# this function if you can provide a useful list of sets for
|
|
210
|
+
# your backend. This list doesn't need to be exhaustive (and
|
|
211
|
+
# is most unlikely to be). It can also return something that
|
|
212
|
+
# would need further expansion using expand_sets.
|
|
213
|
+
def sets_available
|
|
214
|
+
return []
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
# Functions for directly setting/getting parameters
|
|
219
|
+
|
|
220
|
+
# Directly set a named parameter
|
|
221
|
+
def set_param_from_string(param, string)
|
|
222
|
+
description.param_hash[param].set_from_string(self, string)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
protected
|
|
226
|
+
|
|
227
|
+
# Returns a DataSet object for the given _set_. Must be
|
|
228
|
+
# reimplemented by children. The public interface is #dataset.
|
|
229
|
+
#
|
|
230
|
+
# It is *strongly* *recommended* to use
|
|
231
|
+
# Dataset.dataset_from_spec to create the Dataset return
|
|
232
|
+
# values in reimplementations.
|
|
233
|
+
def query_dataset(set)
|
|
234
|
+
raise "query_dataset must be redefined by children !"
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Gets a cached entry or generate it and cache it. See
|
|
238
|
+
# Cache#cache for more details. The cache's meta_data is
|
|
239
|
+
# constructed as following:
|
|
240
|
+
#
|
|
241
|
+
# * the current state of the backend is taken
|
|
242
|
+
# * keys inside _exclude_ are removed.
|
|
243
|
+
# * _supp_info_ is added
|
|
244
|
+
#
|
|
245
|
+
# TODO: get the implementation back again.
|
|
246
|
+
def get_cached_entry(name, exclude = [], supp_info = {}, &code)
|
|
247
|
+
raise YetUnimplemented
|
|
248
|
+
state = save_state
|
|
249
|
+
for k in exclude
|
|
250
|
+
state.delete(k)
|
|
251
|
+
end
|
|
252
|
+
state.merge!(supp_info)
|
|
253
|
+
return @cache.get_cache(name, state, &code)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|