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