ctioga2 0.0

Sign up to get free protection for your applications and to get access to all the features.
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