+ local val = 0
+
+ -- unit map
+ local map = {
+ -- date stuff
+ y = 60 * 60 * 24 * 366,
+ m = 60 * 60 * 24 * 31,
+ w = 60 * 60 * 24 * 7,
+ d = 60 * 60 * 24,
+ h = 60 * 60,
+ min = 60,
+
+ -- storage sizes
+ kb = 1024,
+ mb = 1024 * 1024,
+ gb = 1024 * 1024 * 1024,
+
+ -- storage sizes (si)
+ kib = 1000,
+ mib = 1000 * 1000,
+ gib = 1000 * 1000 * 1000
+ }
+
+ -- parse input string
+ for spec in ustr:lower():gmatch("[0-9%.]+[a-zA-Z]*") do
+
+ local num = spec:gsub("[^0-9%.]+$","")
+ local spn = spec:gsub("^[0-9%.]+", "")
+
+ if map[spn] or map[spn:sub(1,1)] then
+ val = val + num * ( map[spn] or map[spn:sub(1,1)] )
+ else
+ val = val + num
+ end
+ end
+
+
+ return val
+end
+
+--- Combines two or more numerically indexed tables into one.
+-- @param tbl1 Table value to combine
+-- @param tbl2 Table value to combine
+-- @param tblN More values to combine
+-- @return Table value containing all values of given tables
+function combine(...)
+ local result = {}
+ for i, a in ipairs(arg) do
+ for j, v in ipairs(a) do
+ table.insert(result, v)
+ end
+ end
+ return result
+end
+
+--- Checks whether the given table contains the given value.
+-- @param table Table value
+-- @param value Value to search within the given table
+-- @return Boolean indicating wheather the given value occurs within table
+function contains(table, value)
+ for k, v in pairs(table) do
+ if value == v then
+ return k
+ end
+ end
+ return false
+end
+
+--- Update values in given table with the values from the second given table.
+-- Both table are - in fact - merged together.
+-- @param t Table which should be updated
+-- @param updates Table containing the values to update
+-- @return Always nil
+function update(t, updates)
+ for k, v in pairs(updates) do
+ t[k] = v
+ end
+end
+
+--- Clones the given object and return it's copy.
+-- @param object Table value to clone
+-- @param deep Boolean indicating wheather to do recursive cloning
+-- @return Cloned table value
+function clone(object, deep)
+ local copy = {}
+
+ for k, v in pairs(object) do
+ if deep and type(v) == "table" then
+ v = clone(v, deep)
+ end
+ copy[k] = v
+ end
+
+ setmetatable(copy, getmetatable(object))
+
+ return copy
+end
+
+
+--
+-- Byte code manipulation routines
+--
+
+--- Return the current runtime bytecode of the given function. The byte code
+-- will be stripped before it is returned.
+-- @param f Function value to return as bytecode
+-- @return String value containing the bytecode of the given function
+function get_bytecode(f)
+ local d = string.dump(f)
+ return d and strip_bytecode(d)
+end
+
+--- Strips unnescessary lua bytecode from given string. Information like line
+-- numbers and debugging numbers will be discarded. Original version by
+-- Peter Cawley (http://lua-users.org/lists/lua-l/2008-02/msg01158.html)
+-- @param code String value containing the original lua byte code
+-- @return String value containing the stripped lua byte code
+function strip_bytecode(code)
+ local version, format, endian, int, size, ins, num, lnum = code:byte(5, 12)