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