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