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