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