This file is indexed.

/usr/lib/ruby/vendor_ruby/ctioga2/data/backends/backend.rb is in ctioga2 0.10-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# backend.rb : The base of the arcitecture of the Backends
# Copyright (C) 2006, 2009 Vincent Fourmond

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA


require 'ctioga2/utils'
require 'ctioga2/data/backends/description'

module CTioga2

  module Data

    # The Backends are in charge of acquiring DataSet from various
    # data sources.
    module Backends
      
      # This class provides the infrastructure for accessing data sets. It
      # shouldn't be used directly, but rather subclassed and reimplemented.
      # The aim of this class is to provide any software which is interested
      # to retrive data from some source with a consistent way to do so,
      # independent the kind of source accessed.
      #
      # \todo update documentation.
      #
      # Subclasses should:
      # * provide a consistent method for creating themselves,
      #   with as much information as necessary, including options and default
      #   parameters. Actually, their initialize function should take no value
      #   but on the other side, the BackendDescription associated with it
      #   should make it easy to set all the parameters necessary to
      #   get one set of data.
      # * provide a way to fill an OptionParser with their own parameters
      # * provide a way to retrieve the data via named 'sets' (either 2D or 3D
      #   data, depending on the subclass)
      # * provide a way to obtain all meta-informations on one dataset,
      #   such as the date, the meaning of the columns (if any), and so on.
      # * provide a way to know which named sets are available, or at least
      #   a subset (or nothing if we don't know a thing).
      # * wether the actual reading of the data is done at initialization time
      #   or at query time is left to the implementor ;-) !
      #
      # \todo adapt to the new structure.
      #
      # \todo add back filters (with time)
      #
      # \todo add a Cache ?
      class Backend

        # Include logging facilities...
        include CTioga2::Log

        # Import the main description functions into the appropriate
        # namespaces
        extend  BackendDescriptionExtend

        # Backend is a factory, but no autoregistering is made.
        create_factory false

        # Sets up a few things, such as the filters.
        def initialize
        end

        # Returns the BackendDescription associated with this Backend.
        def description
          return self.class.description
        end

        # Creates a description object with the given texts and
        # associates it with the class. It is necessary to have this
        # statement *before* any parameter declaration. If you don't
        # set any description, you will not be able to benefit from
        # the plugin system.  To be used in Backend subclasses, simply
        # this way:
        #
        #  describe "biniou", "Biniou backend", "A backend to deal with Binious"
        #
        def Backend.describe(name, longname, desc, register = true)
          d = BackendDescription.new(self, name, longname, desc, register)
          set_description(d)
        end

        # Returns a hash containing the description of all available
        # backends
        def Backend.list_backends
          return factory_description_hash
        end

        describe 'backend', 'The base class for backends', <<EOD, false
This is the base class for backends. It should never be used directly.
EOD


        # \todo the baseline should not be implemented.
        # It is much more efficient to ;
        # * implement a dataset subtraction command;
        # * use the add-dataset hook to automatically subtract a given
        #   (named ?) buffer.

        # A hook to set a baseline:
        #         param_reader :base_line=, :base_line, "baseline", "Base line",
        #         {:type => :string, }, "Sets a baseline for subsequent data sets"


        # Returns true if the backend can provide data for the given set.
        def has_set?(set)
          return false
        end
        
        alias set? has_set?


        # Public interface to query DataSet from a Backend. Children
        # must redefine #query_dataset rather than this function. This
        # function also applies filters and does othe kinds of
        # transformations
        def dataset(set)
          return query_dataset(set)
        end


        # When converting a user input into a set, a program should
        # *always* use this function, unless it has really good
        # reasons for that.
        #
        # The default implementation is to expand 2##4 to 2, 3, 4. Can
        # be useful even for mathematical stuff.
        #
        # Another thing is recognised and expanded: #<2<i*2>,5> runs
        # the code i*2 with the values from 2 to 5 and returns the
        # result. The code in the middle is a Ruby block, and
        # therefore should be valid !
        #
        # A third expansion is now available: #<a = 2<a * sin(x)>10>
        # will expand into 2*sin(x) , 3*sin(x) ... 10*sin(x) it is
        # different than the previous in the sense that the code in
        # the middle is not a Ruby code, but a mere string, which
        # means there won't be compilation problems.
        #
        # Unless your backend can't accomodate for that, all
        # redefinitions of this function should check for their
        # specific signatures first and call this function if they
        # fail. This way, they will profit from improvements in this
        # code while keeping old stuff working.
        def expand_sets(spec)
          if m = /(\d+)##(\d+)/.match(spec)
            debug { "Using expansion rule #1" }
            a = m[1].to_i
            b = m[2].to_i
            ret = []
            a.upto(b) do |i|
              ret << m.pre_match + i.to_s + m.post_match
            end
            return ret
          elsif m = /\#<(\d+)<(.*?)>(\d+)>/.match(spec)
            debug { "Using expansion rule #2" }
            from = m[1].to_i
            to = m[3].to_i
            debug { "Ruby code used for expansion: {|i| #{m[2]} }" }
            code = eval "proc {|i| #{m[2]} }"
            ret = []
            from.upto(to) do |i|
              ret << m.pre_match + code.call(i).to_s + m.post_match
            end
            return ret
          elsif m = /\#<\s*(\w+)\s*=\s*(\d+)\s*<(.*?)>\s*(\d+)\s*>/.match(spec)
            debug { "Using expansion rule #3" }
            var = m[1]
            from = m[2].to_i
            to = m[4].to_i
            # Then we replace all occurences of the variable
            literal = '"' + m[3].gsub(/\b#{var}\b/, '#{' + var + '}') + '"'
            debug { "Ruby code used for expansion: {|#{var}| #{literal} }" }
            code = eval "proc {|#{var}| #{literal} }"
            ret = []
            from.upto(to) do |i|
              ret << m.pre_match + code.call(i).to_s + m.post_match
            end
            return ret
          end
          # Fallback
          return [spec]
        rescue  Exception => ex
          # In case something went wrong in the eval.
          warn { "An error occured during expansion of '#{spec}': #{ex.message}" }
          debug { "Error backtrace: #{ex.backtrace.join "\n"}" }
          warn {
            "Ignoring, but you're nearly garanteed something will "+
            "fail later on"
          }
          return [spec]
        end

        # Some backends have a pretty good idea of the sets available
        # for use. Some really don't. You can choose to reimplement
        # this function if you can provide a useful list of sets for
        # your backend. This list doesn't need to be exhaustive (and
        # is most unlikely to be). It can also return something that
        # would need further expansion using expand_sets.
        def sets_available
          return []
        end


        # Functions for directly setting/getting parameters

        # Directly set a named parameter
        def set_param_from_string(param, string)
          description.param_hash[param].set_from_string(self, string)
        end

        protected 

        # Returns a DataSet object for the given _set_. Must be
        # reimplemented by children. The public interface is #dataset.
        #
        # It is *strongly* *recommended* to use
        # Dataset.dataset_from_spec to create the Dataset return
        # values in reimplementations.
        def query_dataset(set)
          raise "query_dataset must be redefined by children !"
        end

        # Gets a cached entry or generate it and cache it. See
        # Cache#cache for more details. The cache's meta_data is
        # constructed as following:
        # 
        # * the current state of the backend is taken
        # * keys inside _exclude_ are removed.
        # * _supp_info_ is added
        #
        # \todo get the implementation back again.
        def get_cached_entry(name, exclude = [], supp_info = {}, &code)
          raise YetUnimplemented
          state = save_state
          for k in exclude
            state.delete(k)
          end
          state.merge!(supp_info)
          return @cache.get_cache(name, state, &code)
        end


      end
    end
  end
end