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