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