automate-em 0.0.3 → 0.0.4

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