mvz-live_ast 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES.rdoc +93 -0
  3. data/README.rdoc +419 -0
  4. data/Rakefile +21 -0
  5. data/devel/levitate.rb +853 -0
  6. data/devel/levitate_config.rb +4 -0
  7. data/lib/live_ast.rb +4 -0
  8. data/lib/live_ast/ast_eval.rb +11 -0
  9. data/lib/live_ast/ast_load.rb +15 -0
  10. data/lib/live_ast/base.rb +73 -0
  11. data/lib/live_ast/common.rb +48 -0
  12. data/lib/live_ast/error.rb +20 -0
  13. data/lib/live_ast/evaler.rb +32 -0
  14. data/lib/live_ast/full.rb +2 -0
  15. data/lib/live_ast/irb_spy.rb +43 -0
  16. data/lib/live_ast/linker.rb +122 -0
  17. data/lib/live_ast/loader.rb +60 -0
  18. data/lib/live_ast/reader.rb +26 -0
  19. data/lib/live_ast/replace_eval.rb +121 -0
  20. data/lib/live_ast/replace_load.rb +14 -0
  21. data/lib/live_ast/replace_raise.rb +18 -0
  22. data/lib/live_ast/ruby_parser.rb +36 -0
  23. data/lib/live_ast/ruby_parser/test.rb +197 -0
  24. data/lib/live_ast/ruby_parser/unparser.rb +13 -0
  25. data/lib/live_ast/to_ast.rb +26 -0
  26. data/lib/live_ast/to_ruby.rb +24 -0
  27. data/lib/live_ast/version.rb +3 -0
  28. data/test/ast_eval_feature_test.rb +11 -0
  29. data/test/ast_load_feature_test.rb +11 -0
  30. data/test/attr_test.rb +24 -0
  31. data/test/backtrace_test.rb +158 -0
  32. data/test/covert_define_method_test.rb +23 -0
  33. data/test/def_test.rb +35 -0
  34. data/test/define_method_test.rb +67 -0
  35. data/test/define_singleton_method_test.rb +15 -0
  36. data/test/encoding_test.rb +52 -0
  37. data/test/encoding_test/bad.rb +1 -0
  38. data/test/encoding_test/cp932.rb +6 -0
  39. data/test/encoding_test/default.rb +5 -0
  40. data/test/encoding_test/eucjp.rb +6 -0
  41. data/test/encoding_test/koi8.rb +6 -0
  42. data/test/encoding_test/koi8_shebang.rb +7 -0
  43. data/test/encoding_test/koi8_with_utf8bom.rb +6 -0
  44. data/test/encoding_test/usascii.rb +6 -0
  45. data/test/encoding_test/usascii_with_utf8bom.rb +6 -0
  46. data/test/encoding_test/utf8.rb +6 -0
  47. data/test/encoding_test/utf8bom.rb +6 -0
  48. data/test/encoding_test/utf8bom_only.rb +5 -0
  49. data/test/encoding_test/utf8dos.rb +6 -0
  50. data/test/encoding_test/utf8mac.rb +6 -0
  51. data/test/encoding_test/utf8mac_alt.rb +6 -0
  52. data/test/encoding_test/utf8unix.rb +6 -0
  53. data/test/error_test.rb +116 -0
  54. data/test/eval_test.rb +269 -0
  55. data/test/flush_cache_test.rb +98 -0
  56. data/test/irb_test.rb +25 -0
  57. data/test/lambda_test.rb +56 -0
  58. data/test/load_path_test.rb +78 -0
  59. data/test/load_test.rb +123 -0
  60. data/test/main.rb +140 -0
  61. data/test/nested_test.rb +29 -0
  62. data/test/noninvasive_test.rb +51 -0
  63. data/test/readme_test.rb +16 -0
  64. data/test/recursive_eval_test.rb +52 -0
  65. data/test/redefine_method_test.rb +83 -0
  66. data/test/reload_test.rb +105 -0
  67. data/test/replace_eval_test.rb +405 -0
  68. data/test/rubygems_test.rb +25 -0
  69. data/test/rubyspec_test.rb +39 -0
  70. data/test/singleton_test.rb +25 -0
  71. data/test/stdlib_test.rb +13 -0
  72. data/test/thread_test.rb +44 -0
  73. data/test/to_ast_feature_test.rb +15 -0
  74. data/test/to_ruby_feature_test.rb +15 -0
  75. data/test/to_ruby_test.rb +87 -0
  76. metadata +275 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4396a6fdc53cf54aeb3b6266167f0068549d7d2c
4
+ data.tar.gz: bdd39a8334d5f29c054d72c5125d21347b0dfa19
5
+ SHA512:
6
+ metadata.gz: 81b894dcecb96cb803a65c06d77f99f374a91c877721dd5d6fd220b7f5bf79fe5a951d0426d65973d99d404146d146977995942b0ee7344bf3c6c685f2d128c6
7
+ data.tar.gz: 8ff9b6c24ff52fffd01bb0acca72c391fdab696b5954892da9a98441859eaf109da06798a9362ff347cc221204325ccafdf4c743cc3c08a71e0c3f1d69b3eb10
@@ -0,0 +1,93 @@
1
+
2
+ = live_ast Changes
3
+
4
+ == Version 1.1.0
5
+
6
+ * incorporate default parser in the main gem
7
+ * update RubyParser dependency
8
+ * use binding_of_caller gem instead of boc
9
+
10
+ == Version 1.0.2
11
+
12
+ * handle -unix, -dos, -mac special encoding suffixes
13
+
14
+ == Version 1.0.1
15
+
16
+ * add tests for "def self.f" and "def A.f" (plugins were missing this construct)
17
+
18
+ == Version 1.0.0
19
+
20
+ * no known bugs; API is settled
21
+ * ast_load respects $VERBOSE=true
22
+
23
+ == Version 0.7.3
24
+
25
+ * live_ast/full now available for jruby (via boc gem)
26
+ * fix instance_eval with BasicObject instance
27
+
28
+ == Version 0.7.2
29
+
30
+ * fix old find&replace accident with boc; rubyspec test now enabled by default
31
+
32
+ == Version 0.7.1
33
+
34
+ * fix rubygems problem when parser not loaded after live_ast/full
35
+
36
+ == Version 0.7.0
37
+
38
+ * eval replacement option now included in the gem
39
+ * new 'boc' gem for eval replacement -- no more syntax restrictions
40
+ * add require 'live_ast/full' -- shortcut for live_ast + live_ast/replace_eval
41
+ * rubyspec conformance for require 'live_ast/full'
42
+ * added required_ruby_version to gemspec
43
+ * fixed error when IRB is partially required
44
+
45
+ == Version 0.6.3
46
+
47
+ * minor change for Ruby 1.9.3
48
+
49
+ == Version 0.6.2
50
+
51
+ * simplified irb handling; readline no longer required
52
+ * add -e notes to readme
53
+
54
+ == Version 0.6.1
55
+
56
+ * enable usage inside irb
57
+
58
+ == Version 0.6.0
59
+
60
+ * removed FlushError and NoSourceError -- not possible to distinguish these
61
+ * added more tests
62
+ * refined testing API for plugins
63
+
64
+ == Version 0.5.2
65
+
66
+ * fix default plugin version
67
+
68
+ == Version 0.5.1
69
+
70
+ * protect against user needlessly requiring default parser
71
+
72
+ == Version 0.5.0
73
+
74
+ * new parser plugin API
75
+
76
+ == Version 0.2.3
77
+
78
+ * fix a utf-8 BOM issue
79
+
80
+ == Version 0.2.2
81
+
82
+ * handle utf-8 BOMs in loading
83
+
84
+ == Version 0.2.1
85
+
86
+ * fixed some rdoc issues
87
+ * removed rubyforge references
88
+ * update ruby_parser
89
+ * less MRI-centric tests
90
+
91
+ == Version 0.2.0
92
+
93
+ * initial release
@@ -0,0 +1,419 @@
1
+
2
+ = LiveAST
3
+
4
+ == Summary
5
+
6
+ Live abstract syntax trees of methods and procs. Fork of +live_ast+
7
+ (http://quix.github.com/live_ast).
8
+
9
+ == Synopsis
10
+
11
+ require 'live_ast'
12
+
13
+ class Greet
14
+ def default
15
+ "hello"
16
+ end
17
+ end
18
+
19
+ #### ASTs of methods
20
+
21
+ p Greet.instance_method(:default).to_ast
22
+ # => s(:defn, :default, s(:args), s(:str, "hello"))
23
+
24
+ #### ASTs of lambdas, procs, blocks
25
+
26
+ f = lambda { "foo" }
27
+ p f.to_ast
28
+ # => s(:iter, s(:call, nil, :lambda), s(:args), s(:str, "foo"))
29
+
30
+ def query(&block)
31
+ p block.to_ast
32
+ # => s(:iter, s(:call, nil, :query), s(:args), s(:str, "bar"))
33
+ end
34
+
35
+ query do
36
+ "bar"
37
+ end
38
+
39
+ #### ASTs from dynamic code -- pure ruby version
40
+
41
+ u = ast_eval "lambda { 'dynamic3' }", binding
42
+ p u.to_ast
43
+ # => s(:iter, s(:call, nil, :lambda), s(:args), s(:str, "dynamic3"))
44
+
45
+ ast_eval "def v ; 'dynamic4' ; end", binding
46
+ p method(:v).to_ast
47
+ # => s(:defn, :v, s(:args), s(:str, "dynamic4"))
48
+
49
+ #### ASTs from dynamic code -- fully integrated version
50
+
51
+ require 'live_ast/full'
52
+
53
+ f = eval "lambda { 'dynamic1' }"
54
+ p f.to_ast
55
+ # => s(:iter, s(:call, nil, :lambda), s(:args), s(:str, "dynamic1"))
56
+
57
+ eval "def g ; 'dynamic2' ; end"
58
+ p method(:g).to_ast
59
+ # => s(:defn, :g, s(:args), s(:str, "dynamic2"))
60
+
61
+ == Install
62
+
63
+ % gem install mvz-live_ast
64
+
65
+ == Description
66
+
67
+ LiveAST enables a program to find the ASTs of objects created by
68
+ dynamically generated code. It may be used in a strictly noninvasive
69
+ manner, where no standard classes or methods are modified, or it may
70
+ be transparently integrated into Ruby. The default setting is in
71
+ between.
72
+
73
+ RubyParser is the default parsing engine. To replace it with Ripper,
74
+ <code>gem install live_ast_ripper</code> and then <code>require
75
+ 'live_ast_ripper'</code>. A simple plug-in interface allows LiveAST to
76
+ work with any parser.
77
+
78
+ The advantage of RubyParser is that it gives the traditional ParseTree
79
+ sexps used by tools such as <code>ruby2ruby</code>.
80
+
81
+ LiveAST is thread-safe.
82
+
83
+ Ruby 1.9.2 or higher is required.
84
+
85
+ == Links
86
+
87
+ * Home: https://github.com/mvz/live_ast
88
+ * Feature Requests, Bug Reports: https://github.com/mvz/live_ast/issues
89
+
90
+ == +to_ruby+
91
+
92
+ When the default parser is active,
93
+
94
+ require 'live_ast/to_ruby'
95
+
96
+ will define the +to_ruby+ method for the +Method+, +UnboundMethod+,
97
+ and +Proc+ classes. These methods are one-liners which pass the
98
+ extracted ASTs to <code>ruby2ruby</code>.
99
+
100
+ require 'live_ast/to_ruby'
101
+
102
+ p lambda { |x, y| x + y }.to_ruby # => "lambda { |x, y| (x + y) }"
103
+
104
+ class A
105
+ def f
106
+ "A#f"
107
+ end
108
+ end
109
+
110
+ p A.instance_method(:f).to_ruby # => "def f\n \"A#f\"\nend"
111
+
112
+ In general, +to_ruby+ will hook into the unparser provided by the
113
+ parser plug-in, if one is found.
114
+
115
+ == Pure Ruby and +ast_eval+
116
+
117
+ An essential feature of <code>require 'live_ast'</code> is that it is
118
+ implemented in pure ruby. However since pure ruby is not powerful
119
+ enough to replace +eval+, in this case +ast_eval+ must be used instead
120
+ of +eval+ for AST-accessible objects. +ast_eval+ has the same
121
+ semantics as +eval+ except that the binding argument is required.
122
+
123
+ require 'live_ast'
124
+
125
+ u = ast_eval "lambda { 'dynamic3' }", binding
126
+ p u.to_ast
127
+ # => s(:iter, s(:call, nil, :lambda), s(:args), s(:str, "dynamic3"))
128
+
129
+ == Full Integration
130
+
131
+ In order for LiveAST to be transparent to the user, +eval+ must be
132
+ replaced. This is accomplished with the help of the +binding_of_caller+ gem
133
+ (https://github.com/banister/binding_of_caller).
134
+
135
+ To replace +eval+,
136
+
137
+ require 'live_ast/full'
138
+
139
+ The new AST-electrified +eval+, +instance_eval+, +module_eval+,
140
+ +class_eval+, and <code>Binding#eval</code> all pass RubySpec
141
+ (http://rubyspec.org) with the minor exception of backtraces sometimes
142
+ not matching that of the original +eval+ (see the "Backtraces" section
143
+ below for details).
144
+
145
+ require 'live_ast/full'
146
+
147
+ f = eval "lambda { 'dynamic1' }"
148
+ p f.to_ast
149
+ # => s(:iter, s(:call, nil, :lambda), s(:args), s(:str, "dynamic1"))
150
+
151
+ Since LiveAST itself is pure ruby, any platforms supported by
152
+ +binding_of_caller+ should work with <code>live_ast/full</code>.
153
+
154
+ == Limitations
155
+
156
+ A method or block definition must not share a line with other methods
157
+ or blocks in order for its AST to be accessible.
158
+
159
+ require 'live_ast'
160
+
161
+ class A
162
+ def f ; end ; def g ; end
163
+ end
164
+ A.instance_method(:f).to_ast # => raises LiveAST::MultipleDefinitionsOnSameLineError
165
+
166
+ a = lambda { } ; b = lambda { }
167
+ a.to_ast # => raises LiveAST::MultipleDefinitionsOnSameLineError
168
+
169
+ Code given to the <code>-e</code> command-line switch is not
170
+ AST-accessible.
171
+
172
+ Evaled code appearing before <code>require 'live_ast/full'</code> is
173
+ not AST-accessible.
174
+
175
+ In some circumstances +ast_eval+ and the replaced +eval+ will not give
176
+ the same backtrace as the original +eval+ (next section).
177
+
178
+ ----
179
+ == <em>Technical Issues</em>
180
+
181
+ You can probably skip these next sections. Goodbye.
182
+ ----
183
+
184
+ == Backtraces
185
+
186
+ +ast_eval+ is meant to be compatible with +eval+. For instance the
187
+ first line of +ast_eval+'s backtrace should be identical to that of
188
+ +eval+:
189
+
190
+ require 'live_ast'
191
+
192
+ ast_eval %{ raise "boom" }, binding
193
+ # => test.rb:3:in `<main>': boom (RuntimeError)
194
+
195
+ Let's make a slight change,
196
+
197
+ require 'live_ast'
198
+
199
+ f = ast_eval %{ lambda { raise "boom" } }, binding
200
+ f.call
201
+ # => test.rb|ast@a:3:in `block in <main>': boom (RuntimeError)
202
+
203
+ What the heck is '<code>|ast@a</code>' doing there? LiveAST's
204
+ implementation has just been exposed: each source input is assigned a
205
+ unique key which enables a Ruby object to find its own definition.
206
+
207
+ In the first case above, +ast_eval+ has removed the key from the
208
+ exception backtrace. But in the second case there is no opportunity to
209
+ remove it since +ast_eval+ has already returned.
210
+
211
+ If you find this to be problem---for example if you cannot add a
212
+ filter for the jump-to-location feature in your editor---then +raise+
213
+ may be redefined to strip these tokens,
214
+
215
+ require 'live_ast'
216
+ require 'live_ast/replace_raise'
217
+
218
+ f = ast_eval %{ lambda { raise "boom" } }, binding
219
+ f.call
220
+ # => test.rb:4:in `block in <main>': boom (RuntimeError)
221
+
222
+ However this only applies to a +raise+ call originating from Ruby
223
+ code. An exception from within a native method will likely still
224
+ contain the token in its backtrace (e.g., in MRI the exception raised
225
+ by <code>1/0</code> comes from C).
226
+
227
+ == Replacing the Parser
228
+
229
+ Despite its name, LiveAST knows nothing about ASTs. It merely reports
230
+ what it finds in the line-to-AST hash returned by the parser's +parse+
231
+ method. Replacing the parser class is therefore easy: the only
232
+ specification is that the +parse+ instance method return such a hash.
233
+
234
+ To override the default parser with your own,
235
+
236
+ LiveAST.parser = YourParser
237
+
238
+ To test it, provide some examples of what the ASTs look like in
239
+ <code>YourParser::Test</code>. See +live_ast/ruby_parser+ for
240
+ reference.
241
+
242
+ == Noninvasive Mode
243
+
244
+ For safety purposes, <code>require 'live_ast'</code> performs the
245
+ invasive act of redefining +load+ (but not +require+); otherwise bad
246
+ things can happen to the unwary. The addition of +to_ast+ to a few
247
+ standard Ruby classes is also a meddlesome move.
248
+
249
+ To avoid these modifications,
250
+
251
+ require 'live_ast/base'
252
+
253
+ will provide the essentials of LiveAST but will not touch core classes
254
+ or methods.
255
+
256
+ To select features individually,
257
+
258
+ require 'live_ast/to_ast' # define to_ast for Method, UnboundMethod, Proc
259
+ require 'live_ast/to_ruby' # define to_ruby for Method, UnboundMethod, Proc
260
+ require 'live_ast/ast_eval' # define Kernel#ast_eval
261
+ require 'live_ast/ast_load' # define Kernel#ast_load (mentioned below)
262
+ require 'live_ast/replace_load' # redefine Kernel#load
263
+
264
+ == Noninvasive Interface
265
+
266
+ The following alternative interface is available.
267
+
268
+ require 'live_ast/base'
269
+
270
+ class A
271
+ def f
272
+ "A#f"
273
+ end
274
+ end
275
+
276
+ p LiveAST.ast(A.instance_method(:f))
277
+ # => s(:defn, :f, s(:args), s(:str, "A#f"))
278
+
279
+ p LiveAST.ast(lambda { })
280
+ # => s(:iter, s(:call, nil, :lambda), s(:args))
281
+
282
+ f = LiveAST.eval("lambda { }", binding)
283
+
284
+ p LiveAST.ast(f)
285
+ # => s(:iter, s(:call, nil, :lambda), s(:args))
286
+
287
+ ast_eval # => raises NameError
288
+
289
+ == Reloading Files In Noninvasive Mode
290
+
291
+ Use +ast_load+ or (equivalently) <code>LiveAST.load</code> when
292
+ reloading an AST-aware file.
293
+
294
+ require 'live_ast/ast_load'
295
+ require 'live_ast/to_ast'
296
+
297
+ require "foo"
298
+ Foo.instance_method(:bar).to_ast # caches AST
299
+
300
+ # ... the bar method is changed in foo.rb ...
301
+
302
+ ast_load "foo.rb"
303
+ p Foo.instance_method(:bar).to_ast # => updated AST
304
+
305
+ Note if +load+ is called instead of +ast_load+ then the last line will
306
+ give the old AST,
307
+
308
+ load "foo.rb" # oops! forgot to use ast_load
309
+ p Foo.instance_method(:bar).to_ast # => stale AST
310
+
311
+ Realize that <code>foo.rb</code> may be referenced by an unknown
312
+ number of methods and blocks. If the original <code>foo.rb</code>
313
+ source were dumped in favor of the modified <code>foo.rb</code>, then
314
+ an unknown number of those references would be invalidated (and some
315
+ may even point to the wrong AST).
316
+
317
+ This is the reason for the caching that results in the stale AST
318
+ above. It should now be clear why the default behavior of
319
+ <code>require 'live_ast'</code> is to redefine +load+: doing so
320
+ prevents this problem entirely. On the other hand if it is fully known
321
+ where files are being reloaded (if at all) then there's no need for
322
+ paranoia; the noninvasive option may be the most appropriate.
323
+
324
+ == The Source/AST Cache
325
+
326
+ +ast_eval+ and +load+ cache all incoming code, while
327
+ <code>require</code>d files are cached on a need-to-know basis. When
328
+ an AST is requested, the corresponding source file is parsed and
329
+ discarded, leaving behind method and block ASTs. +to_ast+ removes an
330
+ AST from the cache and attaches it to the appropriate object (a Proc
331
+ or Module).
332
+
333
+ Ignored, unextracted ASTs will therefore linger in the cache. Since
334
+ sexps are generally small there is little need for concern unless one
335
+ is continually evaling/reloading <em>and</em> failing to extract the
336
+ sexps. Nevertheless it is possible that old ASTs will eventually need
337
+ to be garbage collected. To flush the cache,
338
+
339
+ (1) Check that +to_ast+ has been called on all objects whose ASTs are
340
+ desired.
341
+
342
+ (2) Call <code>LiveAST.flush_cache</code>.
343
+
344
+ Calling +to_ast+ prevents the object's AST from being flushed (since
345
+ it grafts the AST onto the object).
346
+
347
+ ASTs of procs and methods whose sources lie in <code>require</code>d
348
+ files will never be flushed. However a method redefined via +ast_eval+
349
+ or +load+ is susceptible to +flush_cache+ even when its original
350
+ definition pointed to a <code>require</code>d file.
351
+
352
+ == About +require+
353
+
354
+ No measures have been taken to detect manipulations of
355
+ <code>$LOADED_FEATURES</code> which would cause +require+ to load the
356
+ same file twice. Though +require+ <em>could</em> be replaced in
357
+ similar fashion to +load+---heading off problems arising from such
358
+ "raw" reloads---the overhead would seem inappropriate in relation to
359
+ the rarity of this case.
360
+
361
+ Therefore the working assumption is that +require+ will load a file
362
+ only once. Furthermore, if a file has not been reloaded then it is
363
+ assumed that the file is unmodified between the moment it is
364
+ <code>require</code>d and the moment the first AST is pulled from it.
365
+
366
+ == Authors
367
+
368
+ * James M. Lawrence < quixoticsycophant@gmail.com >
369
+ * Matijs van Zuijlen < matijs@matijs.net >
370
+
371
+ == License
372
+
373
+ Copyright (c) 2011 James M. Lawrence. All rights reserved.
374
+ Copyright (c) 2014 Matijs van Zuijlen. All rights reserved.
375
+
376
+ Permission is hereby granted, free of charge, to any person
377
+ obtaining a copy of this software and associated documentation files
378
+ (the "Software"), to deal in the Software without restriction,
379
+ including without limitation the rights to use, copy, modify, merge,
380
+ publish, distribute, sublicense, and/or sell copies of the Software,
381
+ and to permit persons to whom the Software is furnished to do so,
382
+ subject to the following conditions:
383
+
384
+ The above copyright notice and this permission notice shall be
385
+ included in all copies or substantial portions of the Software.
386
+
387
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
388
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
389
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
390
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
391
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
392
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
393
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
394
+ SOFTWARE.
395
+
396
+ LiveAST includes the source code of live_ast_ruby_parser, which is licensed as
397
+ follows:
398
+
399
+ Copyright (c) 2011 James M. Lawrence. All rights reserved.
400
+
401
+ Permission is hereby granted, free of charge, to any person
402
+ obtaining a copy of this software and associated documentation files
403
+ (the "Software"), to deal in the Software without restriction,
404
+ including without limitation the rights to use, copy, modify, merge,
405
+ publish, distribute, sublicense, and/or sell copies of the Software,
406
+ and to permit persons to whom the Software is furnished to do so,
407
+ subject to the following conditions:
408
+
409
+ The above copyright notice and this permission notice shall be
410
+ included in all copies or substantial portions of the Software.
411
+
412
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
413
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
414
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
415
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
416
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
417
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
418
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
419
+ SOFTWARE.