rufus-lua 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2009, John Mettraux, Alain Hoang.
2
+ # Copyright (c) 2009-2014, John Mettraux, Alain Hoang.
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -23,7 +23,6 @@
23
23
  #++
24
24
 
25
25
 
26
- #require 'rubygems' # done by the 'client' code
27
26
  require 'ffi'
28
27
 
29
28
 
@@ -36,26 +35,45 @@ module Lua
36
35
  #
37
36
  # locate the dynamic library
38
37
 
39
- paths = Array(
38
+ paths =
40
39
  ENV['LUA_LIB'] ||
41
- Dir.glob('/usr/lib/liblua*.so') +
42
- Dir.glob('/usr/local/lib/liblua*.so') +
43
- Dir.glob('/opt/local/lib/liblua*.so') +
44
- Dir.glob('/usr/lib/liblua*.dylib') +
45
- Dir.glob('/usr/local/lib/liblua*.dylib') +
46
- Dir.glob('/opt/local/lib/liblua*.dylib'))
40
+ # developer points to the right lib
41
+ (
42
+ Dir.glob('/usr/lib/liblua*.so') +
43
+ Dir.glob('/usr/lib/*/liblua*.so') +
44
+ Dir.glob('/usr/local/lib/liblua*.so') +
45
+ Dir.glob('/opt/local/lib/liblua*.so') +
46
+ Dir.glob('/usr/lib/liblua*.dylib') +
47
+ Dir.glob('/usr/local/lib/liblua*.dylib') +
48
+ Dir.glob('/opt/local/lib/liblua*.dylib')
49
+ )
50
+ # or else we attempt to find it from potential locations
47
51
 
48
52
  begin
49
53
 
50
- ffi_lib(*paths)
54
+ ffi_lib_flags(:lazy, :global)
55
+
56
+ ffi_lib(paths)
51
57
 
52
58
  rescue LoadError => le
53
- raise(
54
- "didn't find the lua dylib on your system, " +
55
- "see http://rufus.rubyforge.org/rufus-lua/ to learn how to get it"
59
+
60
+ fail RuntimeError.new(
61
+ "Didn't find the Lua dynamic library on your system. " +
62
+ "Set LUA_LIB in your environment if have that library or " +
63
+ "go to https://github.com/jmettraux/rufus-lua to learn how to " +
64
+ "get it. (paths: #{paths.inspect})"
56
65
  )
57
66
  end
58
67
 
68
+ # Rufus::Lua::Lib.path returns the path to the library used.
69
+ #
70
+ def self.path
71
+
72
+ f = ffi_libraries.first
73
+
74
+ f ? f.name : nil
75
+ end
76
+
59
77
  #
60
78
  # attach functions
61
79
 
@@ -65,6 +83,7 @@ module Lua
65
83
 
66
84
  attach_function :luaL_openlibs, [ :pointer ], :void
67
85
 
86
+ attach_function :lua_call, [ :pointer, :int, :int ], :void
68
87
  %w[ base package string table math io os debug ].each do |libname|
69
88
  attach_function "luaopen_#{libname}", [ :pointer ], :void
70
89
  end
@@ -74,7 +93,7 @@ module Lua
74
93
 
75
94
  attach_function :lua_toboolean, [ :pointer, :int ], :int
76
95
  attach_function :lua_tonumber, [ :pointer, :int ], :double
77
- attach_function :lua_tolstring, [ :pointer, :int, :pointer ], :string
96
+ attach_function :lua_tolstring, [ :pointer, :int, :pointer ], :pointer
78
97
 
79
98
  attach_function :lua_type, [ :pointer, :int ], :int
80
99
  attach_function :lua_typename, [ :pointer, :int ], :string
@@ -97,6 +116,7 @@ module Lua
97
116
  attach_function :lua_pushinteger, [ :pointer, :int ], :pointer
98
117
  attach_function :lua_pushnumber, [ :pointer, :double ], :pointer
99
118
  attach_function :lua_pushstring, [ :pointer, :string ], :pointer
119
+ attach_function :lua_pushlstring, [ :pointer, :pointer, :int ], :pointer
100
120
 
101
121
  attach_function :lua_rawgeti, [ :pointer, :int, :int ], :void
102
122
 
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2009, John Mettraux, Alain Hoang.
2
+ # Copyright (c) 2009-2014, John Mettraux, Alain Hoang.
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -37,7 +37,7 @@ module Rufus::Lua
37
37
  #
38
38
  attr_reader :ref
39
39
 
40
- def initialize (pointer)
40
+ def initialize(pointer)
41
41
 
42
42
  @pointer = pointer
43
43
  @ref = Lib.luaL_ref(@pointer, LUA_REGISTRYINDEX)
@@ -60,7 +60,7 @@ module Rufus::Lua
60
60
  #
61
61
  def load_onto_stack
62
62
 
63
- raise LuaError.new(
63
+ fail RuntimeError.new(
64
64
  "#{self.class} got freed, cannot re-access it directly"
65
65
  ) unless @ref
66
66
 
@@ -71,7 +71,6 @@ module Rufus::Lua
71
71
  #
72
72
  # A Lua function.
73
73
  #
74
- # require 'rubygems'
75
74
  # require 'rufus/lua'
76
75
  #
77
76
  # s = Rufus::Lua::State.new
@@ -88,7 +87,7 @@ module Rufus::Lua
88
87
 
89
88
  # Calls the Lua function.
90
89
  #
91
- def call (*args)
90
+ def call(*args)
92
91
 
93
92
  bottom = stack_top
94
93
 
@@ -98,7 +97,7 @@ module Rufus::Lua
98
97
  args.each { |arg| stack_push(arg) }
99
98
  # push arguments on stack
100
99
 
101
- pcall(bottom, args.length)
100
+ pcall(bottom, args.length, nil, nil, nil)
102
101
  end
103
102
  end
104
103
 
@@ -109,7 +108,7 @@ module Rufus::Lua
109
108
 
110
109
  # Resumes the coroutine
111
110
  #
112
- def resume (*args)
111
+ def resume(*args)
113
112
 
114
113
  bottom = stack_top
115
114
 
@@ -118,7 +117,7 @@ module Rufus::Lua
118
117
  load_onto_stack
119
118
  args.each { |arg| stack_push(arg) }
120
119
 
121
- pcall(bottom, args.length + 1)
120
+ pcall(bottom, args.length + 1, nil, nil, nil)
122
121
  end
123
122
 
124
123
  # Returns the string status of the coroutine :
@@ -131,7 +130,7 @@ module Rufus::Lua
131
130
  fetch_library_method('coroutine.status').load_onto_stack
132
131
  load_onto_stack
133
132
 
134
- pcall(bottom, 1)
133
+ pcall(bottom, 1, nil, nil, nil)
135
134
  end
136
135
  end
137
136
 
@@ -175,7 +174,7 @@ module Rufus::Lua
175
174
 
176
175
  # Returns the value behind the key, or else nil.
177
176
  #
178
- def [] (k)
177
+ def [](k)
179
178
 
180
179
  load_onto_stack # table
181
180
  stack_push(k) # key
@@ -187,7 +186,7 @@ module Rufus::Lua
187
186
  #
188
187
  # TODO : have something for adding in the array part...
189
188
  #
190
- def []= (k, v)
189
+ def []=(k, v)
191
190
 
192
191
  load_onto_stack
193
192
 
@@ -282,7 +281,7 @@ module Rufus::Lua
282
281
  # @s.eval("return { 1, 2, car = 'benz' }").to_a(false)
283
282
  # # => [1.0, 2.0, ["car", "benz"]]
284
283
  #
285
- def to_a (pure=true)
284
+ def to_a(pure=true)
286
285
 
287
286
  h = self.to_h
288
287
 
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2009, John Mettraux, Alain Hoang.
2
+ # Copyright (c) 2009-2014, John Mettraux, Alain Hoang.
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -25,13 +25,6 @@
25
25
 
26
26
  module Rufus::Lua
27
27
 
28
- VERSION = '1.1.0'
29
-
30
- #
31
- # An error class for this gem/library.
32
- #
33
- class LuaError < RuntimeError; end
34
-
35
28
  #
36
29
  # Rufus::Lua::Lib contains all the raw C API Lua methods. The methods
37
30
  # here are shared by all the rufus-lua classes that have to deal with
@@ -82,25 +75,25 @@ module Rufus::Lua
82
75
  #
83
76
  # (Not sure yet about this yet)
84
77
  #
85
- def fetch_library_method (s)
78
+ def fetch_library_method(s)
86
79
 
87
- if m = @pointer.__lib_method_cache[s]
88
- m
89
- else
90
- @pointer.__lib_method_cache[s] = loadstring_and_call("return #{s}")
91
- end
80
+ m = @pointer.__lib_method_cache[s]
81
+ return m if m
82
+
83
+ @pointer.__lib_method_cache[s] =
84
+ loadstring_and_call("return #{s}", nil, nil, nil)
92
85
  end
93
86
 
94
87
  # This method holds the 'eval' mechanism.
95
88
  #
96
- def loadstring_and_call (s)
89
+ def loadstring_and_call(s, binding, filename, lineno)
97
90
 
98
91
  bottom = stack_top
99
92
 
100
93
  err = Lib.luaL_loadbuffer(@pointer, s, Lib.strlen(s), 'line')
101
- raise_if_error('eval:compile', err)
94
+ fail_if_error('eval:compile', err, binding, filename, lineno)
102
95
 
103
- pcall(bottom, 0) # arg_count is set to 0
96
+ pcall(bottom, 0, binding, filename, lineno) # arg_count is set to 0
104
97
  end
105
98
 
106
99
  # Returns a string representation of the state's stack.
@@ -134,7 +127,7 @@ module Rufus::Lua
134
127
 
135
128
  # Outputs the stack to the stdout
136
129
  #
137
- def print_stack (msg=nil)
130
+ def print_stack(msg=nil)
138
131
 
139
132
  puts "\n=stack= #{msg ? "(#{msg})" : ""}"
140
133
  puts "top : #{stack_top}"
@@ -153,7 +146,7 @@ module Rufus::Lua
153
146
  # of the Lua state's stack. There is an optional pos paramter to peek
154
147
  # at other elements of the stack.
155
148
  #
156
- def stack_type_at (pos=-1)
149
+ def stack_type_at(pos=-1)
157
150
 
158
151
  type = Lib.lua_type(@pointer, pos)
159
152
  tname = Lib.lua_typename(@pointer, type)
@@ -164,7 +157,7 @@ module Rufus::Lua
164
157
  # Fetches the top value on the stack (or the one specified by the optional
165
158
  # pos parameter), but does not 'pop' it.
166
159
  #
167
- def stack_fetch (pos=-1)
160
+ def stack_fetch(pos=-1)
168
161
 
169
162
  type, tname = stack_type_at(pos)
170
163
 
@@ -172,7 +165,11 @@ module Rufus::Lua
172
165
 
173
166
  when TNIL then nil
174
167
 
175
- when TSTRING then Lib.lua_tolstring(@pointer, pos, nil)
168
+ when TSTRING then
169
+ len = FFI::MemoryPointer.new(:size_t)
170
+ ptr = Lib.lua_tolstring(@pointer, pos, len)
171
+ ptr.read_string(len.read_long)
172
+
176
173
  when TBOOLEAN then (Lib.lua_toboolean(@pointer, pos) == 1)
177
174
  when TNUMBER then Lib.lua_tonumber(@pointer, pos)
178
175
 
@@ -211,7 +208,7 @@ module Rufus::Lua
211
208
 
212
209
  # Given a Ruby instance, will attempt to push it on the Lua stack.
213
210
  #
214
- def stack_push (o)
211
+ def stack_push(o)
215
212
 
216
213
  return stack_push(o.to_lua) if o.respond_to?(:to_lua)
217
214
 
@@ -225,7 +222,7 @@ module Rufus::Lua
225
222
  when Fixnum then Lib.lua_pushinteger(@pointer, o)
226
223
  when Float then Lib.lua_pushnumber(@pointer, o)
227
224
 
228
- when String then Lib.lua_pushstring(@pointer, o)
225
+ when String then Lib.lua_pushlstring(@pointer, o, o.unpack('C*').size)
229
226
  when Symbol then Lib.lua_pushstring(@pointer, o.to_s)
230
227
 
231
228
  when Hash then stack_push_hash(o)
@@ -239,7 +236,7 @@ module Rufus::Lua
239
236
 
240
237
  # Pushes a hash on top of the Lua stack.
241
238
  #
242
- def stack_push_hash (h)
239
+ def stack_push_hash(h)
243
240
 
244
241
  Lib.lua_createtable(@pointer, 0, h.size)
245
242
  # since we already know the size of the table...
@@ -253,7 +250,7 @@ module Rufus::Lua
253
250
 
254
251
  # Pushes an array on top of the Lua stack.
255
252
  #
256
- def stack_push_array (a)
253
+ def stack_push_array(a)
257
254
 
258
255
  Lib.lua_createtable(@pointer, a.size, 0)
259
256
  # since we already know the size of the table...
@@ -267,21 +264,21 @@ module Rufus::Lua
267
264
 
268
265
  # Loads a Lua global value on top of the stack
269
266
  #
270
- def stack_load_global (name)
267
+ def stack_load_global(name)
271
268
 
272
269
  Lib.lua_getfield(@pointer, LUA_GLOBALSINDEX, name)
273
270
  end
274
271
 
275
272
  # Loads the Lua object registered with the given ref on top of the stack
276
273
  #
277
- def stack_load_ref (ref)
274
+ def stack_load_ref(ref)
278
275
 
279
276
  Lib.lua_rawgeti(@pointer, LUA_REGISTRYINDEX, @ref)
280
277
  end
281
278
 
282
279
  # Returns the result of a function call or a coroutine.resume().
283
280
  #
284
- def return_result (stack_bottom)
281
+ def return_result(stack_bottom)
285
282
 
286
283
  count = stack_top - stack_bottom
287
284
 
@@ -297,14 +294,14 @@ module Rufus::Lua
297
294
  #
298
295
  # Will raise an error in case of failure.
299
296
  #
300
- def pcall (stack_bottom, arg_count)
297
+ def pcall(stack_bottom, arg_count, binding, filename, lineno)
301
298
 
302
299
  #err = Lib.lua_pcall(@pointer, 0, 1, 0)
303
300
  # when there's only 1 return value, use LUA_MULTRET (-1) the
304
301
  # rest of the time
305
302
 
306
303
  err = Lib.lua_pcall(@pointer, arg_count, LUA_MULTRET, 0)
307
- raise_if_error('eval:pcall', err)
304
+ fail_if_error('eval:pcall', err, binding, filename, lineno)
308
305
 
309
306
  return_result(stack_bottom)
310
307
  end
@@ -313,9 +310,9 @@ module Rufus::Lua
313
310
  # Resumes a coroutine (that has been placed, under its arguments,
314
311
  # on top of the stack).
315
312
  #
316
- #def do_resume (stack_bottom, arg_count)
313
+ #def do_resume(stack_bottom, arg_count)
317
314
  # err = Lib.lua_resume(@pointer, arg_count)
318
- # raise_if_error('eval:resume', err)
315
+ # fail_if_error('eval:resume', err, nil, nil, nil)
319
316
  # return_result(stack_bottom)
320
317
  #end
321
318
  #++
@@ -323,7 +320,7 @@ module Rufus::Lua
323
320
  # This method will raise an error with err > 0, else it will immediately
324
321
  # return.
325
322
  #
326
- def raise_if_error (where, err)
323
+ def fail_if_error(kind, err, binding, filename, lineno)
327
324
 
328
325
  return if err < 1
329
326
 
@@ -334,16 +331,16 @@ module Rufus::Lua
334
331
  # the error handler function.
335
332
  # LUA_ERRERR: error while running the error handler function.
336
333
 
337
- s = Lib.lua_tolstring(@pointer, -1, nil)
334
+ s = Lib.lua_tolstring(@pointer, -1, nil).read_string
338
335
  Lib.lua_settop(@pointer, -2)
339
336
 
340
- raise LuaError.new("#{where} : '#{s}' (#{err})")
337
+ fail LuaError.new(kind, err, s, binding, filename, lineno)
341
338
  end
342
339
 
343
340
  # Given the name of a Lua global variable, will return its value (or nil
344
341
  # if there is nothing bound under that name).
345
342
  #
346
- def get_global (name)
343
+ def get_global(name)
347
344
 
348
345
  stack_load_global(name)
349
346
  stack_pop
@@ -373,21 +370,11 @@ module Rufus::Lua
373
370
  # The list may include 'base', 'package', 'table', 'string', 'math', 'io',
374
371
  # 'os' and 'debug'.
375
372
  #
376
- def initialize (include_libs=true)
373
+ def initialize(include_libs=true)
377
374
 
378
375
  @pointer = Lib.luaL_newstate
379
376
 
380
- Array(include_libs).each do |libname|
381
-
382
- if libname == false
383
- break
384
- elsif libname == true
385
- Lib.luaL_openlibs(@pointer)
386
- break
387
- else
388
- Lib.send("luaopen_#{libname}", @pointer)
389
- end
390
- end
377
+ open_libraries(include_libs)
391
378
 
392
379
  #
393
380
  # preparing library methods cache
@@ -406,9 +393,9 @@ module Rufus::Lua
406
393
 
407
394
  # Evaluates a piece (string) of Lua code within the state.
408
395
  #
409
- def eval (s)
396
+ def eval(s, binding=nil, filename=nil, lineno=nil)
410
397
 
411
- loadstring_and_call(s)
398
+ loadstring_and_call(s, binding, filename, lineno)
412
399
  end
413
400
 
414
401
  # Returns a value set at the 'global' level in the state.
@@ -416,9 +403,9 @@ module Rufus::Lua
416
403
  # state.eval('a = 1 + 2')
417
404
  # puts state['a'] # => "3.0"
418
405
  #
419
- def [] (k)
406
+ def [](k)
420
407
 
421
- k.index('.') ? self.eval("return #{k}") : get_global(k)
408
+ k.index('.') ? self.eval("return #{k}") : get_global(k)
422
409
  end
423
410
 
424
411
  # Allows for setting a Lua varible immediately.
@@ -426,7 +413,7 @@ module Rufus::Lua
426
413
  # state['var'] = [ 1, 2, 3 ]
427
414
  # puts state['var'].to_a[0] # => 1
428
415
  #
429
- def []= (k, v)
416
+ def []=(k, v)
430
417
 
431
418
  #puts; puts("#{k} = #{Rufus::Lua.to_lua_s(v)}")
432
419
  self.eval("#{k} = #{Rufus::Lua.to_lua_s(v)}")
@@ -434,7 +421,6 @@ module Rufus::Lua
434
421
 
435
422
  # Binds a Ruby function (callback) in the top environment of Lua
436
423
  #
437
- # require 'rubygems'
438
424
  # require 'rufus/lua'
439
425
  #
440
426
  # s = Rufus::Lua::State.new
@@ -474,7 +460,7 @@ module Rufus::Lua
474
460
  # s.eval(return is_array({ 'a' = 'b' }))
475
461
  # # => false
476
462
  #
477
- def function (name, opts={}, &block)
463
+ def function(name, opts={}, &block)
478
464
 
479
465
  raise 'please pass a block for the body of the function' unless block
480
466
 
@@ -588,6 +574,39 @@ module Rufus::Lua
588
574
  raise "State got closed, cannot proceed" unless @pointer
589
575
  Lib.lua_gc(@pointer, LUA_GCRESTART, 0)
590
576
  end
577
+
578
+ # #open_library(libname) - load a lua library via lua_call().
579
+ #
580
+ # This is needed because is the Lua 5.1 Reference Manual Section 5
581
+ # (http://www.lua.org/manual/5.1/manual.html#5) it says:
582
+ #
583
+ # "The luaopen_* functions (to open libraries) cannot be called
584
+ # directly, like a regular C function. They must be called through
585
+ # Lua, like a Lua function."
586
+ #
587
+ # "..you must call them like any other Lua C function, e.g., by using
588
+ # lua_call."
589
+ #
590
+ # (by Matthew Nielsen - https://github.com/xunker)
591
+ #
592
+ def open_library(libname)
593
+
594
+ Lib.lua_pushcclosure(
595
+ @pointer, lambda { |ptr| Lib.send("luaopen_#{libname}", @pointer) }, 0)
596
+ Lib.lua_pushstring(
597
+ @pointer, (libname.to_s == "base" ? "" : libname.to_s))
598
+ Lib.lua_call(
599
+ @pointer, 1, 0)
600
+ end
601
+
602
+ def open_libraries(libs)
603
+
604
+ if libs == true
605
+ Lib.luaL_openlibs(@pointer)
606
+ elsif libs.is_a?(Array)
607
+ libs.each { |l| open_library(l) }
608
+ end
609
+ end
591
610
  end
592
611
  end
593
612