automate-em 0.0.3 → 0.0.4

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/LICENSE ADDED
@@ -0,0 +1,59 @@
1
+ AutomateEM is copyrighted free software co-owned by Stephen von Takach &
2
+ Advanced Control & Acoustics. The Owner of this software permits you to
3
+ redistribute and/or modify the software under either the terms of the GPL
4
+ version 2 (see the file GPL), or the conditions below ("Ruby License"):
5
+
6
+ 1. You may make and give away verbatim copies of the source form of this
7
+ software without restriction, provided that you retain ALL of the
8
+ original copyright notices and associated disclaimers.
9
+
10
+ 2. You may modify your copy of the software in any way, provided that
11
+ you do at least ONE of the following:
12
+
13
+ a) place your modifications in the Public Domain or otherwise
14
+ make them Freely Available, such as by posting said
15
+ modifications to Usenet or an equivalent medium, or by allowing
16
+ the author to include your modifications in the software.
17
+
18
+ b) use the modified software only within your corporation or
19
+ organization.
20
+
21
+ c) give non-standard binaries non-standard names, with
22
+ instructions on where to get the original software distribution.
23
+
24
+ d) make other distribution arrangements with the Owner.
25
+
26
+ 3. You may distribute the software in object code or binary form,
27
+ provided that you do at least ONE of the following:
28
+
29
+ a) distribute the binaries and library files of the software,
30
+ together with instructions (in a manual page or equivalent)
31
+ on where to get the original distribution.
32
+
33
+ b) accompany the distribution with the machine-readable source of
34
+ the software.
35
+
36
+ c) give non-standard binaries non-standard names, with
37
+ instructions on where to get the original software distribution.
38
+
39
+ d) make other distribution arrangements with the Owner.
40
+
41
+ 4. You may modify and include parts of the software into any other
42
+ software (possibly commercial), provided you comply with the terms in
43
+ Sections 1, 2, and 3 above. But some files in the distribution
44
+ are not written by the Owner, so they may be made available to you
45
+ under different terms.
46
+
47
+ For the list of those files and their copying conditions, see the
48
+ file LEGAL.
49
+
50
+ 5. The scripts and library files supplied as input to or produced as
51
+ output from the software do not automatically fall under the
52
+ copyright of the software, but belong to whoever generated them,
53
+ and may be sold commercially, and may be aggregated with this
54
+ software.
55
+
56
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
57
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
58
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
59
+ PURPOSE.
@@ -24,21 +24,21 @@ h2. Generating module scaffolding
24
24
  From a console
25
25
 
26
26
  # type: @rails g module module/scope/and_name@
27
- #* An example would be: @rails g module NEC/Projectors/NP2000@
28
- #* This will create a file at @app/modules/nec/projectors/np2000.rb@
27
+ #* An example would be: @rails g module NecCorp/Projectors/Np2000@
28
+ #* This will create a file at @app/modules/nec_corp/projectors/np2000.rb@
29
29
  # You will be asked what type of module you would like to generate
30
30
  #* Type: @device@ for a generic device module (a raw TCP or UDP protocol including telnet)
31
31
  #* Type: @service@ for any module that will be interfacing with a HTTP(S) service
32
32
  #* Type: @logic@ to generate a controller/interfacing module
33
33
 
34
- Note: The scope (@NEC/Projectors@ in the example above) is optional and can be as deep or shallow as makes sense.
34
+ Note: The name space (@NecCorp/Projectors@ in the example above) is optional and can be as deep or shallow as makes sense.
35
35
 
36
36
  h2. Writing Modules
37
37
 
38
38
  Please see: "writing modules":https://github.com/stakach/automate-em/wiki/writing-modules
39
39
 
40
40
 
41
- h2. Database Configuration
41
+ h2. System Configuration
42
42
 
43
43
  Please see: "system configuration":https://github.com/stakach/automate-em/wiki/system-configuration
44
44
 
@@ -83,7 +83,7 @@ var AutomateEm = {
83
83
  this.send = send;
84
84
 
85
85
  //
86
- // Requests to recieve notifications of a value change from the server
86
+ // Requests to receive notifications of a value change from the server
87
87
  // Triggers the functions passed in when the server informs us of an update
88
88
  //
89
89
  this.bind = function (events, func) {
@@ -118,7 +118,7 @@ module AutomateEm
118
118
  #
119
119
  # Start the UDP server
120
120
  #
121
- EM.open_datagram_socket "0.0.0.0", 0, DatagramServer
121
+ EM.open_datagram_socket "0.0.0.0", Rails.configuration.automate.datagram_port, DatagramServer
122
122
 
123
123
  #
124
124
  # Load the system based on the database
@@ -50,7 +50,7 @@ module AutomateEm
50
50
 
51
51
  #
52
52
  # TODO:: Consider allowing different dependancies use the same connection
53
- # Means only the first will call received - others must use recieve blocks
53
+ # Means only the first will call received - others must use receive blocks
54
54
  #
55
55
  class DeviceModule
56
56
  @@instances = {} # db id => @instance
@@ -158,7 +158,7 @@ module AutomateEm
158
158
  if !controllerDevice.udp
159
159
  res = ResolverJob.new(controllerDevice.ip)
160
160
  res.callback {|ip|
161
- EM.connect ip, controllerDevice.port, Device::Base, @instance
161
+ EM.connect ip, controllerDevice.port, Device::Base, @instance, false # controllerDevice.udp
162
162
  loaded.call
163
163
  }
164
164
  res.errback {|error|
@@ -176,7 +176,7 @@ module AutomateEm
176
176
  # => TODO::test!!
177
177
  # Call connected
178
178
  #
179
- devBase = DatagramBase.new(@instance)
179
+ devBase = DatagramBase.new(@instance, true)
180
180
  $datagramServer.add_device(controllerDevice, devBase)
181
181
  loaded.call
182
182
  end
@@ -9,7 +9,13 @@ module AutomateEm
9
9
  include DeviceConnection
10
10
 
11
11
  def do_send_data(data)
12
- $datagramServer.do_send_data(DeviceModule.lookup(@parent), data)
12
+ EM.defer do
13
+ $datagramServer.do_send_data(DeviceModule.lookup(@parent), data)
14
+ end
15
+ end
16
+
17
+ def error?
18
+ false
13
19
  end
14
20
  end
15
21
 
@@ -26,7 +32,7 @@ module AutomateEm
26
32
  @ips = {}
27
33
 
28
34
  EM.defer do
29
- System.logger.info 'running datagram server on an ephemeral port'
35
+ System.logger.info 'datagram server is now running'
30
36
  end
31
37
  end
32
38
 
@@ -39,10 +45,10 @@ module AutomateEm
39
45
  port, ip = Socket.unpack_sockaddr_in(get_peername)
40
46
  begin
41
47
  @devices["#{ip}:#{port}"].do_receive_data(data)
42
- rescue
43
- #
44
- # TODO:: error messages here if device is null ect
45
- #
48
+ rescue => e
49
+ EM.defer do
50
+ System.logger.info e.message + "\nDatagram receive failed..."
51
+ end
46
52
  end
47
53
  end
48
54
 
@@ -62,37 +68,36 @@ module AutomateEm
62
68
  text = "#{scheme.ip}:#{scheme.port}"
63
69
  old_ip = @ips[text]
64
70
  if old_ip != ip
65
- EM.schedule do # All modifications are on the reactor thread instead of locking
66
- device = @devices.delete("#{old_ip}:#{scheme.port}")
67
- @ips[text] = ip
68
- @devices["#{ip}:#{scheme.port}"] = device
69
- end
71
+ device = @devices.delete("#{old_ip}:#{scheme.port}")
72
+ @ips[text] = ip
73
+ @devices["#{ip}:#{scheme.port}"] = device
70
74
  end
75
+
71
76
  send_datagram(data, ip, scheme.port)
72
77
  }
73
78
  res.errback {|error|
74
79
  EM.defer do
75
- System.logger.info e.message + " calling UDP send for #{scheme.dependency.actual_name} @ #{scheme.ip} in #{scheme.control_system.name}"
80
+ System.logger.info error.message + " calling UDP send for #{scheme.dependency.actual_name} @ #{scheme.ip} in #{scheme.control_system.name}"
76
81
  end
77
82
  }
78
83
  end
79
84
 
80
85
  def add_device(scheme, device)
81
- EM.schedule do
82
- res = ResolverJob.new(scheme.ip)
83
- res.callback {|ip|
84
- @devices["#{ip}:#{scheme.port}"] = device
85
- @ips["#{scheme.ip}:#{scheme.port}"] = ip
86
- }
87
- res.errback {|error|
88
- @devices["#{scheme.ip}:#{scheme.port}"] = device
89
- @ips["#{scheme.ip}:#{scheme.port}"] = scheme.ip
90
- }
86
+
87
+ res = ResolverJob.new(scheme.ip)
88
+ res.callback {|ip|
89
+ @devices["#{ip}:#{scheme.port}"] = device
90
+ @ips["#{scheme.ip}:#{scheme.port}"] = ip
91
+ }
92
+ res.errback {|error|
93
+ @devices["#{scheme.ip}:#{scheme.port}"] = device
94
+ @ips["#{scheme.ip}:#{scheme.port}"] = scheme.ip
91
95
 
92
96
  EM.defer do
93
- System.logger.info e.message + " adding UDP #{scheme.dependency.actual_name} @ #{scheme.ip} in #{scheme.control_system.name}"
97
+ System.logger.info error.message + " adding UDP #{scheme.dependency.actual_name} @ #{scheme.ip} in #{scheme.control_system.name}"
94
98
  end
95
- end
99
+ }
100
+
96
101
  end
97
102
 
98
103
  def remove_device(scheme)
@@ -100,7 +105,7 @@ module AutomateEm
100
105
  begin
101
106
  ip = @ips.delete("#{scheme.ip}:#{scheme.port}")
102
107
  @devices.delete("#{ip}:#{scheme.port}")
103
- rescue
108
+ rescue => e
104
109
  EM.defer do
105
110
  System.logger.info e.message + " removing UDP #{scheme.dependency.actual_name} @ #{scheme.ip} in #{scheme.control_system.name}"
106
111
  end
@@ -6,13 +6,13 @@ require 'atomic'
6
6
  #
7
7
  module AutomateEm
8
8
  module DeviceConnection
9
- def initialize( parent )
10
- super
9
+ def initialize( parent, udp )
10
+ #super
11
11
 
12
12
  @default_send_options = {
13
13
  :wait => true, # Wait for response
14
14
  :delay => 0, # Delay next send by x.y seconds
15
- :delay_on_recieve => 0, # Delay next send after a recieve by x.y seconds (only works when we are waiting for responses)
15
+ :delay_on_receive => 0, # Delay next send after a receive by x.y seconds (only works when we are waiting for responses)
16
16
  #:emit
17
17
  :max_waits => 3,
18
18
  :callback => nil, # Alternative to the received function
@@ -28,8 +28,8 @@ module AutomateEm
28
28
  :max_buffer => 524288, # 512kb
29
29
  :clear_queue_on_disconnect => false,
30
30
  :flush_buffer_on_disconnect => false,
31
- :priority_bonus => 20,
32
- :inactivity_timeout => 0 # part of make and break options
31
+ :priority_bonus => 20
32
+ # :inactivity_timeout => 0 # part of make and break options
33
33
  # :response_length # an alternative to response_delimiter (lower priority)
34
34
  # :response_delimiter # here instead of a function call
35
35
  }
@@ -61,7 +61,7 @@ module AutomateEm
61
61
  #
62
62
  # State
63
63
  #
64
- @connected = false
64
+ @connected = udp
65
65
  @connecting = false
66
66
  @disconnecting = false
67
67
  @com_paused = true
@@ -70,7 +70,7 @@ module AutomateEm
70
70
  @waiting = false
71
71
  @processing = false
72
72
  @last_sent_at = 0.0
73
- @last_recieve_at = 0.0
73
+ @last_receive_at = 0.0
74
74
  @timeout = nil
75
75
 
76
76
 
@@ -252,7 +252,7 @@ module AutomateEm
252
252
  # NOTE: The buffer cannot be defered otherwise there are concurrency issues
253
253
  #
254
254
  def do_receive_data(data)
255
- @last_recieve_at = Time.now.to_f
255
+ @last_receive_at = Time.now.to_f
256
256
 
257
257
  begin
258
258
  if @config[:response_delimiter].present?
@@ -433,8 +433,8 @@ module AutomateEm
433
433
  @processing = false
434
434
  @waiting = false
435
435
 
436
- if @command[:delay_on_recieve] > 0.0
437
- delay_for = (@last_recieve_at + @command[:delay_on_recieve] - Time.now.to_f)
436
+ if @command[:delay_on_receive] > 0.0
437
+ delay_for = (@last_receive_at + @command[:delay_on_receive] - Time.now.to_f)
438
438
 
439
439
  if delay_for > 0.0
440
440
  EM.add_timer delay_for do
@@ -450,7 +450,7 @@ module AutomateEm
450
450
  end
451
451
 
452
452
  def process_response_complete
453
- if (@make_break && @config[:inactivity_timeout] == 0 && @send_queue.empty?) || @command[:force_disconnect]
453
+ if (@make_break && [nil, 0].include?(@config[:inactivity_timeout]) && @send_queue.empty?) || @command[:force_disconnect]
454
454
  if @connected
455
455
  close_connection_after_writing
456
456
  @disconnecting = true
@@ -608,7 +608,7 @@ module AutomateEm
608
608
  # NOTE:: Same as add parent in device module!!!
609
609
  # TODO:: Should break into a module and include it
610
610
  #
611
- set_comm_inactivity_timeout(@config[:inactivity_timeout])
611
+ set_comm_inactivity_timeout(@config[:inactivity_timeout]) unless @config[:inactivity_timeout].nil?
612
612
  @task_queue.push lambda {
613
613
  EM.defer do
614
614
  @parent[:connected] = true
@@ -7,10 +7,10 @@ module AutomateEm
7
7
 
8
8
  #
9
9
  # This is how sending works
10
- # Send recieves data, turns a mutex on and sends the data
11
- # -- It goes into the recieve mutex critical section and sleeps waiting for a response
10
+ # Send receives data, turns a mutex on and sends the data
11
+ # -- It goes into the receive mutex critical section and sleeps waiting for a response
12
12
  # -- a timeout is used as a backup in case no response is received
13
- # The recieve function does the following
13
+ # The receive function does the following
14
14
  # -- If the send lock is not active it processes the received data
15
15
  # -- otherwise it notifies the send function that data is avaliable
16
16
  #
@@ -15,6 +15,7 @@ module AutomateEm
15
15
  app.config.automate.module_paths = []
16
16
  app.config.automate.log_level = Logger::INFO
17
17
  app.config.automate.encrypt_key = "Lri2B0yvEVag+raqX9uqMFu9LmGoGwbaO8fzNidf"
18
+ app.config.automate.datagram_port = 0 # ephemeral port (random selection)
18
19
  end
19
20
 
20
21
  #
@@ -209,7 +209,7 @@ class HTML5Monitor
209
209
  if command.length == 2
210
210
  @system.send_command(command[0], command[1], *data[:data])
211
211
  else
212
- AutomateEm::System.logger.info "-- in html5.rb, recieve : invalid command received - #{data[:command]} --"
212
+ AutomateEm::System.logger.info "-- in html5.rb, receive : invalid command received - #{data[:command]} --"
213
213
  end
214
214
  end
215
215
  }
@@ -219,7 +219,7 @@ class HTML5Monitor
219
219
  logger = @system.nil? ? AutomateEm::System.logger : @system.logger
220
220
  }
221
221
  AutomateEm.print_error(logger, e, {
222
- :message => "in html5.rb, recieve : probably malformed JSON data",
222
+ :message => "in html5.rb, receive : probably malformed JSON data",
223
223
  :level => Logger::ERROR
224
224
  })
225
225
  shutdown
@@ -10,6 +10,9 @@ module AutomateEm
10
10
  #
11
11
  def setbase(base)
12
12
  @base = base
13
+ class << self
14
+ undef setbase
15
+ end
13
16
  end
14
17
 
15
18
 
@@ -50,7 +50,7 @@ module AutomateEm
50
50
  @default_request_options = {
51
51
  :wait => true, # Wait for response
52
52
  :delay => 0, # Delay next request by x.y seconds
53
- :delay_on_recieve => 0, # Delay next request after a recieve by x.y seconds (only works when we are waiting for responses)
53
+ :delay_on_receive => 0, # Delay next request after a receive by x.y seconds (only works when we are waiting for responses)
54
54
  #:emit
55
55
  :retries => 2,
56
56
  :priority => 50,
@@ -104,7 +104,7 @@ module AutomateEm
104
104
  # State
105
105
  #
106
106
  @last_sent_at = 0.0
107
- @last_recieve_at = 0.0
107
+ @last_receive_at = 0.0
108
108
 
109
109
 
110
110
  #
@@ -371,7 +371,7 @@ module AutomateEm
371
371
 
372
372
 
373
373
  #
374
- # Caled from recieve
374
+ # Caled from receive
375
375
  #
376
376
  def process_response(response, command)
377
377
  EM.defer do
@@ -427,8 +427,8 @@ module AutomateEm
427
427
 
428
428
  #else result == :abort || result == :success || result == true || waits and retries exceeded
429
429
 
430
- if command[:delay_on_recieve] > 0.0
431
- delay_for = (@last_recieve_at + command[:delay_on_recieve] - Time.now.to_f)
430
+ if command[:delay_on_receive] > 0.0
431
+ delay_for = (@last_receive_at + command[:delay_on_receive] - Time.now.to_f)
432
432
 
433
433
  if delay_for > 0.0
434
434
  EM.add_timer delay_for do
@@ -76,7 +76,7 @@ module AutomateEm
76
76
  if @emit_hasnt_occured.present?
77
77
  begin
78
78
  if @emit_hasnt_occured.has_key?(status)
79
- @base.received_lock.mon_exit # check we are in the recieved queue
79
+ @base.received_lock.mon_exit # check we are in the received queue
80
80
  @base.received_lock.mon_enter
81
81
 
82
82
  block = @emit_hasnt_occured.delete(status)
@@ -23,24 +23,22 @@ module AutomateEm
23
23
  def initialize(jobs, index, lock)
24
24
  @jobs = jobs
25
25
  @index = index
26
+ @lock = lock
26
27
  @job = @jobs[@index] # only ever called from within the lock
27
28
  end
28
29
 
29
30
 
30
31
  def unschedule
31
- EM.schedule do
32
- begin
33
- @job.unschedule
34
- @jobs.delete(@index)
35
- rescue
36
- end
32
+ @lock.synchronize do
33
+ @job.unschedule
34
+ @jobs.delete(@index)
37
35
  end
38
36
  end
39
37
 
40
38
  protected
41
39
 
42
40
  def method_missing(name, *args, &block)
43
- EM.schedule do
41
+ @lock.synchronize do
44
42
  @job.send(name, *args, &block)
45
43
  end
46
44
  end
@@ -53,10 +51,11 @@ module AutomateEm
53
51
  def initialize
54
52
  @jobs = {}
55
53
  @index = 0
54
+ @job_lock = Mutex.new
56
55
  end
57
56
 
58
57
  def clear_jobs
59
- EM.schedule do
58
+ @job_lock.synchronize do
60
59
  @jobs.each_value do |job|
61
60
  job.unschedule
62
61
  end
@@ -69,49 +68,46 @@ module AutomateEm
69
68
  protected
70
69
 
71
70
  def method_missing(name, *args, &block)
72
- EM.schedule do
73
- begin
74
- if block.present?
75
- job = nil
71
+ @job_lock.synchronize do
72
+ if block.present?
73
+ job = nil
74
+
75
+ if [:in, :at].include?(name)
76
+ index = @index # local variable for the block
76
77
 
77
- if [:in, :at].include?(name)
78
- index = @index # local variable for the block
79
-
80
- job = AutomateEm::scheduler.send(name, *args) do
81
- begin
82
- block.call
83
- rescue => e
84
- AutomateEm.print_error(System.logger, e, :message => "Error in one off scheduled event")
85
- ensure
86
- EM.schedule do
87
- @jobs.delete(index)
88
- end
78
+ job = AutomateEm::scheduler.send(name, *args) do
79
+ begin
80
+ block.call
81
+ rescue => e
82
+ AutomateEm.print_error(System.logger, e, :message => "Error in one off scheduled event")
83
+ ensure
84
+ @job_lock.synchronize do
85
+ @jobs.delete(index)
89
86
  end
90
87
  end
91
- else
92
- job = AutomateEm::scheduler.send(name, *args) do
93
- begin
94
- block.call
95
- rescue => e
96
- AutomateEm.print_error(System.logger, e, :message => "Error in repeated scheduled event")
97
- end
88
+ end
89
+ else
90
+ job = AutomateEm::scheduler.send(name, *args) do
91
+ begin
92
+ block.call
93
+ rescue => e
94
+ AutomateEm.print_error(System.logger, e, :message => "Error in repeated scheduled event")
98
95
  end
99
96
  end
97
+ end
98
+
99
+ if job.present?
100
+ @jobs[@index] = job
101
+ job = JobProxy.new(@jobs, @index, @job_lock)
100
102
 
101
- if job.present?
102
- @jobs[@index] = job
103
- job = JobProxy.new(@jobs, @index, @job_lock)
104
-
105
- @index += 1
106
-
107
- return job
108
- end
103
+ @index += 1
109
104
 
110
- return nil
111
- else
112
- AutomateEm::scheduler.send(name, *args, &block)
105
+ return job
113
106
  end
114
- rescue
107
+
108
+ return nil
109
+ else
110
+ AutomateEm::scheduler.send(name, *args, &block)
115
111
  end
116
112
  end
117
113
  end
@@ -1,3 +1,3 @@
1
1
  module AutomateEm
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: automate-em
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-23 00:00:00.000000000 Z
12
+ date: 2012-07-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirements:
35
35
  - - ! '>='
36
36
  - !ruby/object:Gem::Version
37
- version: 1.0.0.beta.4.1
37
+ version: 1.0.0.rc.4
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
- version: 1.0.0.beta.4.1
45
+ version: 1.0.0.rc.4
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: em-priority-queue
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -240,7 +240,7 @@ files:
240
240
  - lib/generators/module/module_generator.rb
241
241
  - lib/generators/module/USAGE
242
242
  - lib/tasks/automate-em_tasks.rake
243
- - LGPL3-LICENSE
243
+ - LICENSE
244
244
  - Rakefile
245
245
  - README.textile
246
246
  - test/automate-em_test.rb
@@ -1,165 +0,0 @@
1
- GNU LESSER GENERAL PUBLIC LICENSE
2
- Version 3, 29 June 2007
3
-
4
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
5
- Everyone is permitted to copy and distribute verbatim copies
6
- of this license document, but changing it is not allowed.
7
-
8
-
9
- This version of the GNU Lesser General Public License incorporates
10
- the terms and conditions of version 3 of the GNU General Public
11
- License, supplemented by the additional permissions listed below.
12
-
13
- 0. Additional Definitions.
14
-
15
- As used herein, "this License" refers to version 3 of the GNU Lesser
16
- General Public License, and the "GNU GPL" refers to version 3 of the GNU
17
- General Public License.
18
-
19
- "The Library" refers to a covered work governed by this License,
20
- other than an Application or a Combined Work as defined below.
21
-
22
- An "Application" is any work that makes use of an interface provided
23
- by the Library, but which is not otherwise based on the Library.
24
- Defining a subclass of a class defined by the Library is deemed a mode
25
- of using an interface provided by the Library.
26
-
27
- A "Combined Work" is a work produced by combining or linking an
28
- Application with the Library. The particular version of the Library
29
- with which the Combined Work was made is also called the "Linked
30
- Version".
31
-
32
- The "Minimal Corresponding Source" for a Combined Work means the
33
- Corresponding Source for the Combined Work, excluding any source code
34
- for portions of the Combined Work that, considered in isolation, are
35
- based on the Application, and not on the Linked Version.
36
-
37
- The "Corresponding Application Code" for a Combined Work means the
38
- object code and/or source code for the Application, including any data
39
- and utility programs needed for reproducing the Combined Work from the
40
- Application, but excluding the System Libraries of the Combined Work.
41
-
42
- 1. Exception to Section 3 of the GNU GPL.
43
-
44
- You may convey a covered work under sections 3 and 4 of this License
45
- without being bound by section 3 of the GNU GPL.
46
-
47
- 2. Conveying Modified Versions.
48
-
49
- If you modify a copy of the Library, and, in your modifications, a
50
- facility refers to a function or data to be supplied by an Application
51
- that uses the facility (other than as an argument passed when the
52
- facility is invoked), then you may convey a copy of the modified
53
- version:
54
-
55
- a) under this License, provided that you make a good faith effort to
56
- ensure that, in the event an Application does not supply the
57
- function or data, the facility still operates, and performs
58
- whatever part of its purpose remains meaningful, or
59
-
60
- b) under the GNU GPL, with none of the additional permissions of
61
- this License applicable to that copy.
62
-
63
- 3. Object Code Incorporating Material from Library Header Files.
64
-
65
- The object code form of an Application may incorporate material from
66
- a header file that is part of the Library. You may convey such object
67
- code under terms of your choice, provided that, if the incorporated
68
- material is not limited to numerical parameters, data structure
69
- layouts and accessors, or small macros, inline functions and templates
70
- (ten or fewer lines in length), you do both of the following:
71
-
72
- a) Give prominent notice with each copy of the object code that the
73
- Library is used in it and that the Library and its use are
74
- covered by this License.
75
-
76
- b) Accompany the object code with a copy of the GNU GPL and this license
77
- document.
78
-
79
- 4. Combined Works.
80
-
81
- You may convey a Combined Work under terms of your choice that,
82
- taken together, effectively do not restrict modification of the
83
- portions of the Library contained in the Combined Work and reverse
84
- engineering for debugging such modifications, if you also do each of
85
- the following:
86
-
87
- a) Give prominent notice with each copy of the Combined Work that
88
- the Library is used in it and that the Library and its use are
89
- covered by this License.
90
-
91
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
92
- document.
93
-
94
- c) For a Combined Work that displays copyright notices during
95
- execution, include the copyright notice for the Library among
96
- these notices, as well as a reference directing the user to the
97
- copies of the GNU GPL and this license document.
98
-
99
- d) Do one of the following:
100
-
101
- 0) Convey the Minimal Corresponding Source under the terms of this
102
- License, and the Corresponding Application Code in a form
103
- suitable for, and under terms that permit, the user to
104
- recombine or relink the Application with a modified version of
105
- the Linked Version to produce a modified Combined Work, in the
106
- manner specified by section 6 of the GNU GPL for conveying
107
- Corresponding Source.
108
-
109
- 1) Use a suitable shared library mechanism for linking with the
110
- Library. A suitable mechanism is one that (a) uses at run time
111
- a copy of the Library already present on the user's computer
112
- system, and (b) will operate properly with a modified version
113
- of the Library that is interface-compatible with the Linked
114
- Version.
115
-
116
- e) Provide Installation Information, but only if you would otherwise
117
- be required to provide such information under section 6 of the
118
- GNU GPL, and only to the extent that such information is
119
- necessary to install and execute a modified version of the
120
- Combined Work produced by recombining or relinking the
121
- Application with a modified version of the Linked Version. (If
122
- you use option 4d0, the Installation Information must accompany
123
- the Minimal Corresponding Source and Corresponding Application
124
- Code. If you use option 4d1, you must provide the Installation
125
- Information in the manner specified by section 6 of the GNU GPL
126
- for conveying Corresponding Source.)
127
-
128
- 5. Combined Libraries.
129
-
130
- You may place library facilities that are a work based on the
131
- Library side by side in a single library together with other library
132
- facilities that are not Applications and are not covered by this
133
- License, and convey such a combined library under terms of your
134
- choice, if you do both of the following:
135
-
136
- a) Accompany the combined library with a copy of the same work based
137
- on the Library, uncombined with any other library facilities,
138
- conveyed under the terms of this License.
139
-
140
- b) Give prominent notice with the combined library that part of it
141
- is a work based on the Library, and explaining where to find the
142
- accompanying uncombined form of the same work.
143
-
144
- 6. Revised Versions of the GNU Lesser General Public License.
145
-
146
- The Free Software Foundation may publish revised and/or new versions
147
- of the GNU Lesser General Public License from time to time. Such new
148
- versions will be similar in spirit to the present version, but may
149
- differ in detail to address new problems or concerns.
150
-
151
- Each version is given a distinguishing version number. If the
152
- Library as you received it specifies that a certain numbered version
153
- of the GNU Lesser General Public License "or any later version"
154
- applies to it, you have the option of following the terms and
155
- conditions either of that published version or of any later version
156
- published by the Free Software Foundation. If the Library as you
157
- received it does not specify a version number of the GNU Lesser
158
- General Public License, you may choose any version of the GNU Lesser
159
- General Public License ever published by the Free Software Foundation.
160
-
161
- If the Library as you received it specifies that a proxy can decide
162
- whether future versions of the GNU Lesser General Public License shall
163
- apply, that proxy's public statement of acceptance of any version is
164
- permanent authorization for you to choose that version for the
165
- Library.