* Separated CBI from LuCI Web
[project/luci.git] / core / src / 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 module("luci.util", package.seeall)
28
29
30 -- Lua simplified Python-style OO class support emulation
31 function class(base)
32 local class = {}
33
34 local create = function(class, ...)
35 local inst = {}
36 setmetatable(inst, {__index = class})
37
38 if inst.__init__ then
39 local stat, err = pcall(inst.__init__, inst, ...)
40 if not stat then
41 error(err)
42 end
43 end
44
45 return inst
46 end
47
48 local classmeta = {__call = create}
49
50 if base then
51 classmeta.__index = base
52 end
53
54 setmetatable(class, classmeta)
55 return class
56 end
57
58
59 -- Clones an object (deep on-demand)
60 function clone(object, deep)
61 local copy = {}
62
63 for k, v in pairs(object) do
64 if deep and type(v) == "table" then
65 v = clone(v, deep)
66 end
67 copy[k] = v
68 end
69
70 setmetatable(copy, getmetatable(object))
71
72 return copy
73 end
74
75
76 -- Combines two or more numerically indexed tables into one
77 function combine(...)
78 local result = {}
79 for i, a in ipairs(arg) do
80 for j, v in ipairs(a) do
81 table.insert(result, v)
82 end
83 end
84 return result
85 end
86
87
88 -- Checks whether a table has an object "value" in it
89 function contains(table, value)
90 for k,v in pairs(table) do
91 if value == v then
92 return true
93 end
94 end
95 return false
96 end
97
98
99 -- Dumps a table to stdout (useful for testing and debugging)
100 function dumptable(t, i)
101 i = i or 0
102 for k,v in pairs(t) do
103 print(string.rep("\t", i) .. k, v)
104 if type(v) == "table" then
105 dumptable(v, i+1)
106 end
107 end
108 end
109
110
111 -- Escapes all occurences of c in s
112 function escape(s, c)
113 c = c or "\\"
114 return s:gsub(c, "\\" .. c)
115 end
116
117
118 -- Populate obj in the scope of f as key
119 function extfenv(f, key, obj)
120 local scope = getfenv(f)
121 scope[key] = obj
122 end
123
124
125 -- Checks whether an object is an instanceof class
126 function instanceof(object, class)
127 local meta = getmetatable(object)
128 while meta and meta.__index do
129 if meta.__index == class then
130 return true
131 end
132 meta = getmetatable(meta.__index)
133 end
134 return false
135 end
136
137
138 -- Creates valid XML PCDATA from a string
139 function pcdata(value)
140 value = value:gsub("&", "&amp;")
141 value = value:gsub('"', "&quot;")
142 value = value:gsub("'", "&apos;")
143 value = value:gsub("<", "&lt;")
144 return value:gsub(">", "&gt;")
145 end
146
147
148 -- Resets the scope of f doing a shallow copy of its scope into a new table
149 function resfenv(f)
150 setfenv(f, clone(getfenv(f)))
151 end
152
153
154 -- Splits a string into an array
155 function split(str, pat, max, regex)
156 pat = pat or "\n"
157 max = max or #str
158
159 local t = {}
160 local c = 1
161
162 if #str == 0 then
163 return {""}
164 end
165
166 if #pat == 0 then
167 return nil
168 end
169
170 if max == 0 then
171 return str
172 end
173
174 repeat
175 local s, e = str:find(pat, c, not regex)
176 table.insert(t, str:sub(c, s and s - 1))
177 max = max - 1
178 c = e and e + 1 or #str + 1
179 until not s or max < 0
180
181 return t
182 end
183
184 -- Removes whitespace from beginning and end of a string
185 function trim(str)
186 local s = str:gsub("^%s*(.-)%s*$", "%1")
187 return s
188 end
189
190 -- Updates given table with new values
191 function update(t, updates)
192 for k, v in pairs(updates) do
193 t[k] = v
194 end
195 end
196
197
198 -- Updates the scope of f with "extscope"
199 function updfenv(f, extscope)
200 update(getfenv(f), extscope)
201 end
202
203
204 -- Validates a variable
205 function validate(value, cast_number, cast_int)
206 if cast_number or cast_int then
207 value = tonumber(value)
208 end
209
210 if cast_int and value and not(value % 1 == 0) then
211 value = nil
212 end
213
214 return value
215 end