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.
Files changed (82) hide show
  1. data/COPYING +339 -0
  2. data/Changelog +6 -0
  3. data/bin/ctioga2 +26 -0
  4. data/lib/ctioga2/commands/arguments.rb +58 -0
  5. data/lib/ctioga2/commands/commands.rb +258 -0
  6. data/lib/ctioga2/commands/doc/doc.rb +118 -0
  7. data/lib/ctioga2/commands/doc/documentation-commands.rb +119 -0
  8. data/lib/ctioga2/commands/doc/help.rb +95 -0
  9. data/lib/ctioga2/commands/doc/html.rb +230 -0
  10. data/lib/ctioga2/commands/doc/introspection.rb +211 -0
  11. data/lib/ctioga2/commands/doc/man.rb +279 -0
  12. data/lib/ctioga2/commands/doc/markup.rb +359 -0
  13. data/lib/ctioga2/commands/general-commands.rb +119 -0
  14. data/lib/ctioga2/commands/general-types.rb +118 -0
  15. data/lib/ctioga2/commands/groups.rb +73 -0
  16. data/lib/ctioga2/commands/interpreter.rb +257 -0
  17. data/lib/ctioga2/commands/parsers/command-line.rb +187 -0
  18. data/lib/ctioga2/commands/parsers/file.rb +186 -0
  19. data/lib/ctioga2/commands/strings.rb +303 -0
  20. data/lib/ctioga2/commands/type.rb +100 -0
  21. data/lib/ctioga2/commands/variables.rb +101 -0
  22. data/lib/ctioga2/data/backends/backend.rb +260 -0
  23. data/lib/ctioga2/data/backends/backends.rb +39 -0
  24. data/lib/ctioga2/data/backends/backends/gnuplot.rb +140 -0
  25. data/lib/ctioga2/data/backends/backends/math.rb +121 -0
  26. data/lib/ctioga2/data/backends/backends/text.rb +335 -0
  27. data/lib/ctioga2/data/backends/description.rb +405 -0
  28. data/lib/ctioga2/data/backends/factory.rb +73 -0
  29. data/lib/ctioga2/data/backends/parameter.rb +109 -0
  30. data/lib/ctioga2/data/datacolumn.rb +245 -0
  31. data/lib/ctioga2/data/dataset.rb +233 -0
  32. data/lib/ctioga2/data/filters.rb +131 -0
  33. data/lib/ctioga2/data/merge.rb +43 -0
  34. data/lib/ctioga2/data/point.rb +72 -0
  35. data/lib/ctioga2/data/stack.rb +294 -0
  36. data/lib/ctioga2/graphics/coordinates.rb +73 -0
  37. data/lib/ctioga2/graphics/elements.rb +111 -0
  38. data/lib/ctioga2/graphics/elements/containers.rb +111 -0
  39. data/lib/ctioga2/graphics/elements/curve2d.rb +155 -0
  40. data/lib/ctioga2/graphics/elements/element.rb +90 -0
  41. data/lib/ctioga2/graphics/elements/primitive.rb +256 -0
  42. data/lib/ctioga2/graphics/elements/subplot.rb +140 -0
  43. data/lib/ctioga2/graphics/generator.rb +68 -0
  44. data/lib/ctioga2/graphics/legends.rb +108 -0
  45. data/lib/ctioga2/graphics/legends/area.rb +199 -0
  46. data/lib/ctioga2/graphics/legends/items.rb +183 -0
  47. data/lib/ctioga2/graphics/legends/provider.rb +58 -0
  48. data/lib/ctioga2/graphics/legends/storage.rb +65 -0
  49. data/lib/ctioga2/graphics/root.rb +209 -0
  50. data/lib/ctioga2/graphics/styles.rb +30 -0
  51. data/lib/ctioga2/graphics/styles/axes.rb +247 -0
  52. data/lib/ctioga2/graphics/styles/background.rb +122 -0
  53. data/lib/ctioga2/graphics/styles/base.rb +115 -0
  54. data/lib/ctioga2/graphics/styles/carrays.rb +53 -0
  55. data/lib/ctioga2/graphics/styles/curve.rb +101 -0
  56. data/lib/ctioga2/graphics/styles/drawable.rb +87 -0
  57. data/lib/ctioga2/graphics/styles/factory.rb +351 -0
  58. data/lib/ctioga2/graphics/styles/legend.rb +63 -0
  59. data/lib/ctioga2/graphics/styles/plot.rb +410 -0
  60. data/lib/ctioga2/graphics/styles/sets.rb +64 -0
  61. data/lib/ctioga2/graphics/styles/texts.rb +277 -0
  62. data/lib/ctioga2/graphics/subplot-commands.rb +141 -0
  63. data/lib/ctioga2/graphics/types.rb +188 -0
  64. data/lib/ctioga2/graphics/types/bijection.rb +79 -0
  65. data/lib/ctioga2/graphics/types/boundaries.rb +170 -0
  66. data/lib/ctioga2/graphics/types/boxes.rb +157 -0
  67. data/lib/ctioga2/graphics/types/dimensions.rb +157 -0
  68. data/lib/ctioga2/graphics/types/point.rb +247 -0
  69. data/lib/ctioga2/log.rb +97 -0
  70. data/lib/ctioga2/metabuilder/type.rb +316 -0
  71. data/lib/ctioga2/metabuilder/types.rb +39 -0
  72. data/lib/ctioga2/metabuilder/types/coordinates.rb +124 -0
  73. data/lib/ctioga2/metabuilder/types/dates.rb +43 -0
  74. data/lib/ctioga2/metabuilder/types/lists.rb +188 -0
  75. data/lib/ctioga2/metabuilder/types/numbers.rb +97 -0
  76. data/lib/ctioga2/metabuilder/types/strings.rb +93 -0
  77. data/lib/ctioga2/metabuilder/types/styles.rb +178 -0
  78. data/lib/ctioga2/plotmaker.rb +677 -0
  79. data/lib/ctioga2/postprocess.rb +115 -0
  80. data/lib/ctioga2/utils.rb +120 -0
  81. data/setup.rb +1586 -0
  82. 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