7877e6ff4e35661d2ca0d39f5a75840ea44b9710
[project/luci.git] / modules / luci-base / luasrc / util.lua
1 --[[
2 LuCI - Utility library
3
4 Description:
5 Several common useful Lua functions
6
7 License:
8 Copyright 2008 Steven Barth <steven@midlink.org>
9
10 Licensed under the Apache License, Version 2.0 (the "License");
11 you may not use this file except in compliance with the License.
12 You may obtain a copy of the License at
13
14         http://www.apache.org/licenses/LICENSE-2.0
15
16 Unless required by applicable law or agreed to in writing, software
17 distributed under the License is distributed on an "AS IS" BASIS,
18 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 See the License for the specific language governing permissions and
20 limitations under the License.
21
22 ]]--
23
24 local io = require "io"
25 local math = require "math"
26 local table = require "table"
27 local debug = require "debug"
28 local ldebug = require "luci.debug"
29 local string = require "string"
30 local coroutine = require "coroutine"
31 local tparser = require "luci.template.parser"
32
33 local _ubus = require "ubus"
34 local _ubus_connection = nil
35
36 local getmetatable, setmetatable = getmetatable, setmetatable
37 local rawget, rawset, unpack = rawget, rawset, unpack
38 local tostring, type, assert = tostring, type, assert
39 local ipairs, pairs, next, loadstring = ipairs, pairs, next, loadstring
40 local require, pcall, xpcall = require, pcall, xpcall
41 local collectgarbage, get_memory_limit = collectgarbage, get_memory_limit
42
43 --- LuCI utility functions.
44 module "luci.util"
45
46 --
47 -- Pythonic string formatting extension
48 --
49 getmetatable("").__mod = function(a, b)
50         if not b then
51                 return a
52         elseif type(b) == "table" then
53                 for k, _ in pairs(b) do if type(b[k]) == "userdata" then b[k] = tostring(b[k]) end end
54                 return a:format(unpack(b))
55         else
56                 if type(b) == "userdata" then b = tostring(b) end
57                 return a:format(b)
58         end
59 end
60
61
62 --
63 -- Class helper routines
64 --
65
66 -- Instantiates a class
67 local function _instantiate(class, ...)
68         local inst = setmetatable({}, {__index = class})
69
70         if inst.__init__ then
71                 inst:__init__(...)
72         end
73
74         return inst
75 end
76
77 --- Create a Class object (Python-style object model).
78 -- The class object can be instantiated by calling itself.
79 -- Any class functions or shared parameters can be attached to this object.
80 -- Attaching a table to the class object makes this table shared between
81 -- all instances of this class. For object parameters use the __init__ function.
82 -- Classes can inherit member functions and values from a base class.
83 -- Class can be instantiated by calling them. All parameters will be passed
84 -- to the __init__ function of this class - if such a function exists.
85 -- The __init__ function must be used to set any object parameters that are not shared
86 -- with other objects of this class. Any return values will be ignored.
87 -- @param base  The base class to inherit from (optional)
88 -- @return              A class object
89 -- @see                 instanceof
90 -- @see                 clone
91 function class(base)
92         return setmetatable({}, {
93                 __call  = _instantiate,
94                 __index = base
95         })
96 end
97
98 --- Test whether the given object is an instance of the given class.
99 -- @param object        Object instance
100 -- @param class         Class object to test against
101 -- @return                      Boolean indicating whether the object is an instance
102 -- @see                         class
103 -- @see                         clone
104 function instanceof(object, class)
105         local meta = getmetatable(object)
106         while meta and meta.__index do
107                 if meta.__index == class then
108                         return true
109                 end
110                 meta = getmetatable(meta.__index)
111         end
112         return false
113 end
114
115
116 --
117 -- Scope manipulation routines
118 --
119
120 local tl_meta = {
121         __mode = "k",
122
123         __index = function(self, key)
124                 local t = rawget(self, coxpt[coroutine.running()]
125                  or coroutine.running() or 0)
126                 return t and t[key]
127         end,
128
129         __newindex = function(self, key, value)
130                 local c = coxpt[coroutine.running()] or coroutine.running() or 0
131                 local r = rawget(self, c)
132                 if not r then
133                         rawset(self, c, { [key] = value })
134                 else
135                         r[key] = value
136                 end
137         end
138 }
139
140 --- Create a new or get an already existing thread local store associated with
141 -- the current active coroutine. A thread local store is private a table object
142 -- whose values can't be accessed from outside of the running coroutine.
143 -- @return      Table value representing the corresponding thread local store
144 function threadlocal(tbl)
145         return setmetatable(tbl or {}, tl_meta)
146 end
147
148
149 --
150 -- Debugging routines
151 --
152
153 --- Write given object to stderr.
154 -- @param obj   Value to write to stderr
155 -- @return              Boolean indicating whether the write operation was successful
156 function perror(obj)
157         return io.stderr:write(tostring(obj) .. "\n")
158 end
159
160 --- Recursively dumps a table to stdout, useful for testing and debugging.
161 -- @param t     Table value to dump
162 -- @param maxdepth      Maximum depth
163 -- @return      Always nil
164 function dumptable(t, maxdepth, i, seen)
165         i = i or 0
166         seen = seen or setmetatable({}, {__mode="k"})
167
168         for k,v in pairs(t) do
169                 perror(string.rep("\t", i) .. tostring(k) .. "\t" .. tostring(v))
170                 if type(v) == "table" and (not maxdepth or i < maxdepth) then
171                         if not seen[v] then
172                                 seen[v] = true
173                                 dumptable(v, maxdepth, i+1, seen)
174                         else
175                                 perror(string.rep("\t", i) .. "*** RECURSION ***")
176                         end
177                 end
178         end
179 end
180
181
182 --
183 -- String and data manipulation routines
184 --
185
186 --- Create valid XML PCDATA from given string.
187 -- @param value String value containing the data to escape
188 -- @return              String value containing the escaped data
189 function pcdata(value)
190         return value and tparser.pcdata(tostring(value))
191 end
192
193 --- Strip HTML tags from given string.
194 -- @param value String containing the HTML text
195 -- @return      String with HTML tags stripped of
196 function striptags(value)
197         return value and tparser.striptags(tostring(value))
198 end
199
200 --- Splits given string on a defined separator sequence and return a table
201 -- containing the resulting substrings. The optional max parameter specifies
202 -- the number of bytes to process, regardless of the actual length of the given
203 -- string. The optional last parameter, regex, specifies whether the separator
204 -- sequence is interpreted as regular expression.
205 -- @param str           String value containing the data to split up
206 -- @param pat           String with separator pattern (optional, defaults to "\n")
207 -- @param max           Maximum times to split (optional)
208 -- @param regex         Boolean indicating whether to interpret the separator
209 --                                      pattern as regular expression (optional, default is false)
210 -- @return                      Table containing the resulting substrings
211 function split(str, pat, max, regex)
212         pat = pat or "\n"
213         max = max or #str
214
215         local t = {}
216         local c = 1
217
218         if #str == 0 then
219                 return {""}
220         end
221
222         if #pat == 0 then
223                 return nil
224         end
225
226         if max == 0 then
227                 return str
228         end
229
230         repeat
231                 local s, e = str:find(pat, c, not regex)
232                 max = max - 1
233                 if s and max < 0 then
234                         t[#t+1] = str:sub(c)
235                 else
236                         t[#t+1] = str:sub(c, s and s - 1)
237                 end
238                 c = e and e + 1 or #str + 1
239         until not s or max < 0
240
241         return t
242 end
243
244 --- Remove leading and trailing whitespace from given string value.
245 -- @param str   String value containing whitespace padded data
246 -- @return              String value with leading and trailing space removed
247 function trim(str)
248         return (str:gsub("^%s*(.-)%s*$", "%1"))
249 end
250
251 --- Count the occurences of given substring in given string.
252 -- @param str           String to search in
253 -- @param pattern       String containing pattern to find
254 -- @return                      Number of found occurences
255 function cmatch(str, pat)
256         local count = 0
257         for _ in str:gmatch(pat) do count = count + 1 end
258         return count
259 end
260
261 --- Return a matching iterator for the given value. The iterator will return
262 -- one token per invocation, the tokens are separated by whitespace. If the
263 -- input value is a table, it is transformed into a string first. A nil value
264 -- will result in a valid interator which aborts with the first invocation.
265 -- @param val           The value to scan (table, string or nil)
266 -- @return                      Iterator which returns one token per call
267 function imatch(v)
268         if type(v) == "table" then
269                 local k = nil
270                 return function()
271                         k = next(v, k)
272                         return v[k]
273                 end
274
275         elseif type(v) == "number" or type(v) == "boolean" then
276                 local x = true
277                 return function()
278                         if x then
279                                 x = false
280                                 return tostring(v)
281                         end
282                 end
283
284         elseif type(v) == "userdata" or type(v) == "string" then
285                 return tostring(v):gmatch("%S+")
286         end
287
288         return function() end
289 end
290
291 --- Parse certain units from the given string and return the canonical integer
292 -- value or 0 if the unit is unknown. Upper- or lower case is irrelevant.
293 -- Recognized units are:
294 --      o "y"   - one year   (60*60*24*366)
295 --  o "m"       - one month  (60*60*24*31)
296 --  o "w"       - one week   (60*60*24*7)
297 --  o "d"       - one day    (60*60*24)
298 --  o "h"       - one hour       (60*60)
299 --  o "min"     - one minute (60)
300 --  o "kb"  - one kilobyte (1024)
301 --  o "mb"      - one megabyte (1024*1024)
302 --  o "gb"      - one gigabyte (1024*1024*1024)
303 --  o "kib" - one si kilobyte (1000)
304 --  o "mib"     - one si megabyte (1000*1000)
305 --  o "gib"     - one si gigabyte (1000*1000*1000)
306 -- @param ustr  String containing a numerical value with trailing unit
307 -- @return              Number containing the canonical value
308 function parse_units(ustr)
309
310         local val = 0
311
312         -- unit map
313         local map = {
314                 -- date stuff
315                 y   = 60 * 60 * 24 * 366,
316                 m   = 60 * 60 * 24 * 31,
317                 w   = 60 * 60 * 24 * 7,
318                 d   = 60 * 60 * 24,
319                 h   = 60 * 60,
320                 min = 60,
321
322                 -- storage sizes
323                 kb  = 1024,
324                 mb  = 1024 * 1024,
325                 gb  = 1024 * 1024 * 1024,
326
327                 -- storage sizes (si)
328                 kib = 1000,
329                 mib = 1000 * 1000,
330                 gib = 1000 * 1000 * 1000
331         }
332
333         -- parse input string
334         for spec in ustr:lower():gmatch("[0-9%.]+[a-zA-Z]*") do
335
336                 local num = spec:gsub("[^0-9%.]+$","")
337                 local spn = spec:gsub("^[0-9%.]+", "")
338
339                 if map[spn] or map[spn:sub(1,1)] then
340                         val = val + num * ( map[spn] or map[spn:sub(1,1)] )
341                 else
342                         val = val + num
343                 end
344         end
345
346
347         return val
348 end
349
350 -- also register functions above in the central string class for convenience
351 string.pcdata      = pcdata
352 string.striptags   = striptags
353 string.split       = split
354 string.trim        = trim
355 string.cmatch      = cmatch
356 string.parse_units = parse_units
357
358
359 --- Appends numerically indexed tables or single objects to a given table.
360 -- @param src   Target table
361 -- @param ...   Objects to insert
362 -- @return              Target table
363 function append(src, ...)
364         for i, a in ipairs({...}) do
365                 if type(a) == "table" then
366                         for j, v in ipairs(a) do
367                                 src[#src+1] = v
368                         end
369                 else
370                         src[#src+1] = a
371                 end
372         end
373         return src
374 end
375
376 --- Combines two or more numerically indexed tables and single objects into one table.
377 -- @param tbl1  Table value to combine
378 -- @param tbl2  Table value to combine
379 -- @param ...   More tables to combine
380 -- @return              Table value containing all values of given tables
381 function combine(...)
382         return append({}, ...)
383 end
384
385 --- Checks whether the given table contains the given value.
386 -- @param table Table value
387 -- @param value Value to search within the given table
388 -- @return              Boolean indicating whether the given value occurs within table
389 function contains(table, value)
390         for k, v in pairs(table) do
391                 if value == v then
392                         return k
393                 end
394         end
395         return false
396 end
397
398 --- Update values in given table with the values from the second given table.
399 -- Both table are - in fact - merged together.
400 -- @param t                     Table which should be updated
401 -- @param updates       Table containing the values to update
402 -- @return                      Always nil
403 function update(t, updates)
404         for k, v in pairs(updates) do
405                 t[k] = v
406         end
407 end
408
409 --- Retrieve all keys of given associative table.
410 -- @param t     Table to extract keys from
411 -- @return      Sorted table containing the keys
412 function keys(t)
413         local keys = { }
414         if t then
415                 for k, _ in kspairs(t) do
416                         keys[#keys+1] = k
417                 end
418         end
419         return keys
420 end
421
422 --- Clones the given object and return it's copy.
423 -- @param object        Table value to clone
424 -- @param deep          Boolean indicating whether to do recursive cloning
425 -- @return                      Cloned table value
426 function clone(object, deep)
427         local copy = {}
428
429         for k, v in pairs(object) do
430                 if deep and type(v) == "table" then
431                         v = clone(v, deep)
432                 end
433                 copy[k] = v
434         end
435
436         return setmetatable(copy, getmetatable(object))
437 end
438
439
440 --- Create a dynamic table which automatically creates subtables.
441 -- @return      Dynamic Table
442 function dtable()
443         return setmetatable({}, { __index =
444                 function(tbl, key)
445                         return rawget(tbl, key)
446                          or rawget(rawset(tbl, key, dtable()), key)
447                 end
448         })
449 end
450
451
452 -- Serialize the contents of a table value.
453 function _serialize_table(t, seen)
454         assert(not seen[t], "Recursion detected.")
455         seen[t] = true
456
457         local data  = ""
458         local idata = ""
459         local ilen  = 0
460
461         for k, v in pairs(t) do
462                 if type(k) ~= "number" or k < 1 or math.floor(k) ~= k or ( k - #t ) > 3 then
463                         k = serialize_data(k, seen)
464                         v = serialize_data(v, seen)
465                         data = data .. ( #data > 0 and ", " or "" ) ..
466                                 '[' .. k .. '] = ' .. v
467                 elseif k > ilen then
468                         ilen = k
469                 end
470         end
471
472         for i = 1, ilen do
473                 local v = serialize_data(t[i], seen)
474                 idata = idata .. ( #idata > 0 and ", " or "" ) .. v
475         end
476
477         return idata .. ( #data > 0 and #idata > 0 and ", " or "" ) .. data
478 end
479
480 --- Recursively serialize given data to lua code, suitable for restoring
481 -- with loadstring().
482 -- @param val   Value containing the data to serialize
483 -- @return              String value containing the serialized code
484 -- @see                 restore_data
485 -- @see                 get_bytecode
486 function serialize_data(val, seen)
487         seen = seen or setmetatable({}, {__mode="k"})
488
489         if val == nil then
490                 return "nil"
491         elseif type(val) == "number" then
492                 return val
493         elseif type(val) == "string" then
494                 return "%q" % val
495         elseif type(val) == "boolean" then
496                 return val and "true" or "false"
497         elseif type(val) == "function" then
498                 return "loadstring(%q)" % get_bytecode(val)
499         elseif type(val) == "table" then
500                 return "{ " .. _serialize_table(val, seen) .. " }"
501         else
502                 return '"[unhandled data type:' .. type(val) .. ']"'
503         end
504 end
505
506 --- Restore data previously serialized with serialize_data().
507 -- @param str   String containing the data to restore
508 -- @return              Value containing the restored data structure
509 -- @see                 serialize_data
510 -- @see                 get_bytecode
511 function restore_data(str)
512         return loadstring("return " .. str)()
513 end
514
515
516 --
517 -- Byte code manipulation routines
518 --
519
520 --- Return the current runtime bytecode of the given data. The byte code
521 -- will be stripped before it is returned.
522 -- @param val   Value to return as bytecode
523 -- @return              String value containing the bytecode of the given data
524 function get_bytecode(val)
525         local code
526
527         if type(val) == "function" then
528                 code = string.dump(val)
529         else
530                 code = string.dump( loadstring( "return " .. serialize_data(val) ) )
531         end
532
533         return code -- and strip_bytecode(code)
534 end
535
536 --- Strips unnescessary lua bytecode from given string. Information like line
537 -- numbers and debugging numbers will be discarded. Original version by
538 -- Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
539 -- @param code  String value containing the original lua byte code
540 -- @return              String value containing the stripped lua byte code
541 function strip_bytecode(code)
542         local version, format, endian, int, size, ins, num, lnum = code:byte(5, 12)
543         local subint
544         if endian == 1 then
545                 subint = function(code, i, l)
546                         local val = 0
547                         for n = l, 1, -1 do
548                                 val = val * 256 + code:byte(i + n - 1)
549                         end
550                         return val, i + l
551                 end
552         else
553                 subint = function(code, i, l)
554                         local val = 0
555                         for n = 1, l, 1 do
556                                 val = val * 256 + code:byte(i + n - 1)
557                         end
558                         return val, i + l
559                 end
560         end
561
562         local function strip_function(code)
563                 local count, offset = subint(code, 1, size)
564                 local stripped = { string.rep("\0", size) }
565                 local dirty = offset + count
566                 offset = offset + count + int * 2 + 4
567                 offset = offset + int + subint(code, offset, int) * ins
568                 count, offset = subint(code, offset, int)
569                 for n = 1, count do
570                         local t
571                         t, offset = subint(code, offset, 1)
572                         if t == 1 then
573                                 offset = offset + 1
574                         elseif t == 4 then
575                                 offset = offset + size + subint(code, offset, size)
576                         elseif t == 3 then
577                                 offset = offset + num
578                         elseif t == 254 or t == 9 then
579                                 offset = offset + lnum
580                         end
581                 end
582                 count, offset = subint(code, offset, int)
583                 stripped[#stripped+1] = code:sub(dirty, offset - 1)
584                 for n = 1, count do
585                         local proto, off = strip_function(code:sub(offset, -1))
586                         stripped[#stripped+1] = proto
587                         offset = offset + off - 1
588                 end
589                 offset = offset + subint(code, offset, int) * int + int
590                 count, offset = subint(code, offset, int)
591                 for n = 1, count do
592                         offset = offset + subint(code, offset, size) + size + int * 2
593                 end
594                 count, offset = subint(code, offset, int)
595                 for n = 1, count do
596                         offset = offset + subint(code, offset, size) + size
597                 end
598                 stripped[#stripped+1] = string.rep("\0", int * 3)
599                 return table.concat(stripped), offset
600         end
601
602         return code:sub(1,12) .. strip_function(code:sub(13,-1))
603 end
604
605
606 --
607 -- Sorting iterator functions
608 --
609
610 function _sortiter( t, f )
611         local keys = { }
612
613         local k, v
614         for k, v in pairs(t) do
615                 keys[#keys+1] = k
616         end
617
618         local _pos = 0
619
620         table.sort( keys, f )
621
622         return function()
623                 _pos = _pos + 1
624                 if _pos <= #keys then
625                         return keys[_pos], t[keys[_pos]], _pos
626                 end
627         end
628 end
629
630 --- Return a key, value iterator which returns the values sorted according to
631 -- the provided callback function.
632 -- @param t     The table to iterate
633 -- @param f A callback function to decide the order of elements
634 -- @return      Function value containing the corresponding iterator
635 function spairs(t,f)
636         return _sortiter( t, f )
637 end
638
639 --- Return a key, value iterator for the given table.
640 -- The table pairs are sorted by key.
641 -- @param t     The table to iterate
642 -- @return      Function value containing the corresponding iterator
643 function kspairs(t)
644         return _sortiter( t )
645 end
646
647 --- Return a key, value iterator for the given table.
648 -- The table pairs are sorted by value.
649 -- @param t     The table to iterate
650 -- @return      Function value containing the corresponding iterator
651 function vspairs(t)
652         return _sortiter( t, function (a,b) return t[a] < t[b] end )
653 end
654
655
656 --
657 -- System utility functions
658 --
659
660 --- Test whether the current system is operating in big endian mode.
661 -- @return      Boolean value indicating whether system is big endian
662 function bigendian()
663         return string.byte(string.dump(function() end), 7) == 0
664 end
665
666 --- Execute given commandline and gather stdout.
667 -- @param command       String containing command to execute
668 -- @return                      String containing the command's stdout
669 function exec(command)
670         local pp   = io.popen(command)
671         local data = pp:read("*a")
672         pp:close()
673
674         return data
675 end
676
677 --- Return a line-buffered iterator over the output of given command.
678 -- @param command       String containing the command to execute
679 -- @return                      Iterator
680 function execi(command)
681         local pp = io.popen(command)
682
683         return pp and function()
684                 local line = pp:read()
685
686                 if not line then
687                         pp:close()
688                 end
689
690                 return line
691         end
692 end
693
694 -- Deprecated
695 function execl(command)
696         local pp   = io.popen(command)
697         local line = ""
698         local data = {}
699
700         while true do
701                 line = pp:read()
702                 if (line == nil) then break end
703                 data[#data+1] = line
704         end
705         pp:close()
706
707         return data
708 end
709
710 --- Issue an ubus call.
711 -- @param object                String containing the ubus object to call
712 -- @param method                String containing the ubus method to call
713 -- @param values                Table containing the values to pass
714 -- @return                      Table containin the ubus result
715 function ubus(object, method, data)
716         if not _ubus_connection then
717                 _ubus_connection = _ubus.connect()
718                 assert(_ubus_connection, "Unable to establish ubus connection")
719         end
720
721         if object and method then
722                 if type(data) ~= "table" then
723                         data = { }
724                 end
725                 return _ubus_connection:call(object, method, data)
726         elseif object then
727                 return _ubus_connection:signatures(object)
728         else
729                 return _ubus_connection:objects()
730         end
731 end
732
733 --- Returns the absolute path to LuCI base directory.
734 -- @return              String containing the directory path
735 function libpath()
736         return require "nixio.fs".dirname(ldebug.__file__)
737 end
738
739
740 --
741 -- Coroutine safe xpcall and pcall versions modified for Luci
742 -- original version:
743 -- coxpcall 1.13 - Copyright 2005 - Kepler Project (www.keplerproject.org)
744 --
745 -- Copyright © 2005 Kepler Project.
746 -- Permission is hereby granted, free of charge, to any person obtaining a
747 -- copy of this software and associated documentation files (the "Software"),
748 -- to deal in the Software without restriction, including without limitation
749 -- the rights to use, copy, modify, merge, publish, distribute, sublicense,
750 -- and/or sell copies of the Software, and to permit persons to whom the
751 -- Software is furnished to do so, subject to the following conditions:
752 --
753 -- The above copyright notice and this permission notice shall be
754 -- included in all copies or substantial portions of the Software.
755 --
756 -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
757 -- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
758 -- OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
759 -- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
760 -- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
761 -- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
762 -- OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
763
764 local performResume, handleReturnValue
765 local oldpcall, oldxpcall = pcall, xpcall
766 coxpt = {}
767 setmetatable(coxpt, {__mode = "kv"})
768
769 -- Identity function for copcall
770 local function copcall_id(trace, ...)
771   return ...
772 end
773
774 --- This is a coroutine-safe drop-in replacement for Lua's "xpcall"-function
775 -- @param f             Lua function to be called protected
776 -- @param err   Custom error handler
777 -- @param ...   Parameters passed to the function
778 -- @return              A boolean whether the function call succeeded and the return
779 --                              values of either the function or the error handler
780 function coxpcall(f, err, ...)
781         local res, co = oldpcall(coroutine.create, f)
782         if not res then
783                 local params = {...}
784                 local newf = function() return f(unpack(params)) end
785                 co = coroutine.create(newf)
786         end
787         local c = coroutine.running()
788         coxpt[co] = coxpt[c] or c or 0
789
790         return performResume(err, co, ...)
791 end
792
793 --- This is a coroutine-safe drop-in replacement for Lua's "pcall"-function
794 -- @param f             Lua function to be called protected
795 -- @param ...   Parameters passed to the function
796 -- @return              A boolean whether the function call succeeded and the returns
797 --                              values of the function or the error object
798 function copcall(f, ...)
799         return coxpcall(f, copcall_id, ...)
800 end
801
802 -- Handle return value of protected call
803 function handleReturnValue(err, co, status, ...)
804         if not status then
805                 return false, err(debug.traceback(co, (...)), ...)
806         end
807
808         if coroutine.status(co) ~= 'suspended' then
809                 return true, ...
810         end
811
812         return performResume(err, co, coroutine.yield(...))
813 end
814
815 -- Resume execution of protected function call
816 function performResume(err, co, ...)
817         return handleReturnValue(err, co, coroutine.resume(co, ...))
818 end