Browse Source

Add doxify.sh to generate HTML code documentation using ldoc; update documentation in several utility files.

feature/buffermax
Wouter R 8 years ago
parent
commit
07ca14e35c
  1. 1
      .gitignore
  2. 4
      README
  3. 12
      README.md
  4. 18
      doxify.sh
  5. 7
      src/conf_defaults.lua
  6. 41
      src/util/logger.lua
  7. 91
      src/util/settings.lua
  8. 13
      src/util/utils.lua

1
.gitignore

@ -1 +1,2 @@
docs
misc

4
README

@ -1,4 +0,0 @@
WiFi box OpenWRT firmware package
=================================
Documentation can be found in the source code and on the wiki: <http://doodle3d.com/wiki>.

12
README.md

@ -0,0 +1,12 @@
WiFi box OpenWRT firmware package
=================================
General documentation can be found on the wiki: <http://doodle3d.com/wiki>. Source code documentation can be generated, see below.
Documentation
-------------
The script 'doxify.sh' generates HTML documentation of the source code in the directory 'docs'.
Make sure the 'ldoc' program is installed on your machine and the LDOC variable in the script points there.
On OSX, this can be accomplished by installing it through luarocks (run `sudo luarocks install ldoc`). Luarocks can be installed using [MacPorts](http://www.macports.org/). After installing that, the command would be `sudo port install luarocks`.

18
doxify.sh

@ -0,0 +1,18 @@
#!/bin/sh
# Generate Lua source code documentation using ldoc. Change LDOC to the path of your luadoc executable and change WIFIBOX_BASE_DIR to the location of your wifibox source tree, or "." if you really want a relative output directory.
# All given options are forwarded to ldoc, -a is already being passed by default.
LDOC=/opt/local/share/luarocks/bin/ldoc
WIFIBOX_BASE_DIR=~/Files/_devel/eclipse-workspace/wifibox
HTML_PATH=$WIFIBOX_BASE_DIR/docs
SRC_DIR=$WIFIBOX_BASE_DIR/src
FILESPEC=$WIFIBOX_BASE_DIR/src #replace by config.ld so we can also specify README.md?
$LDOC -d $HTML_PATH $FILESPEC -a -f markdown $@
if [ $? -eq 127 ]; then
echo "$0: It looks like the ldoc program could not be found, please configure the LDOC variable correctly and make sure ldoc is installed on your system."
echo "$0: By default, this script expects ldoc has been installed with luarocks on OSX, which in turn is installed with macports."
fi

7
src/conf_defaults.lua

@ -1,4 +1,5 @@
--[[
--[[--
TODO: finish documentation
This file contains all valid configuration keys, their default values and optional constraints.
The table names are used as configuration key names, where underscores ('_') may be used to denote semi-categories.
The settings interface replaces periods ('.') by underscores so for instance 'network.ap.address' will
@ -105,13 +106,13 @@ M.printer_useSubLayers = {
M.printer_firstLayerSlow = {
default = true,
type = 'float',
type = 'bool',
description = 'Print the first layer slowly to get a more stable start',
}
M.printer_autoWarmUp = {
default = true,
type = 'float',
type = 'bool',
description = '',
}

41
src/util/logger.lua

@ -1,26 +1,30 @@
--[[--
TODO: ldoc: @{} ref in init() tformat
TODO: use macros/type definitions to document rest modules (to auto-match things like 'M.<func>_NAME%')?
TODO: finish documentation
]]
local utils = require('util.utils')
local M = {}
local logLevel, logVerbose, logStream
M.LEVEL = {'debug', 'info', 'warn', 'error', 'fatal'}
--- Available log levels.
M.LEVEL = {
'debug', -- for debug messages
'info', -- for informational messages
'warn', -- for warnings (something is wrong/fishy but not neccesarily problematic)
'error', -- for recoverable errors
'fatal' -- for unrecoverable errors
}
-- M.LEVEL already has idx=>name entries, now create name=>idx entries
for i,v in ipairs(M.LEVEL) do
M.LEVEL[v] = i
end
function M:init(level, verbose)
logLevel = level or M.LEVEL.warn
logVerbose = verbose or false
logStream = stream or io.stdout
end
-- pass nil as stream to reset to stdout
function M:setStream(stream)
logStream = stream or io.stdout
end
local function log(level, msg, verbose)
if level >= logLevel then
@ -36,6 +40,21 @@ local function log(level, msg, verbose)
end
end
--- Initializes the logger.
-- @tparam @{util.logger.LEVEL} level Minimum level of messages to log.
-- @tparam bool verbose Write verbose log messages (include file/line inforomation).
function M:init(level, verbose)
logLevel = level or M.LEVEL.warn
logVerbose = verbose or false
logStream = stream or io.stdout
end
-- pass nil as stream to reset to stdout
function M:setStream(stream)
logStream = stream or io.stdout
end
function M:debug(msg, verbose) log(M.LEVEL.debug, msg, verbose); return true end
function M:info(msg, verbose) log(M.LEVEL.info, msg, verbose); return true end
function M:warn(msg, verbose) log(M.LEVEL.warn, msg, verbose); return true end

91
src/util/settings.lua

@ -1,29 +1,39 @@
--[[
The settings interface reads and writes its configuration using UCI.
The corresponding config file is /etc/config/wifibox. To have an initial
set of reasonable settings (and allow users to easily return to them),
any key not found in the UCI configuration is looked up in the (immutable)
'base configuration' (base_config.lua). This file also contains constraints
to check if newly set values are valid.
--[[--
The settings interface reads and writes configuration keys using UCI.
All keys have pre-defined defaults in @{conf_defaults} which will be used
if no value is stored in the UCI config. The UCI config file is
'/etc/config/wifibox'.
The default values guarantee there will always be a set of reasonable settings
to use and provide a clear overview of all existing configuration keys as well.
By the way, returning correct values in get()/fromUciValue() for booleans has been fixed at a
relatively convenient time purely thanks to the unit tests...just to indicate they are useful. :)
]]--
By the way, returning correct values in get()/fromUciValue() for booleans has
been fixed at a relatively convenient time purely thanks to the unit tests...
just to indicate how useful they are. :)
]]
local uci = require('uci').cursor()
local utils = require('util.utils')
local baseconfig = require('conf_defaults')
local uci = require('uci').cursor()
local M = {}
local UCI_CONFIG_NAME = 'wifibox' -- the file under /etc/config
--- UCI config name (i.e. file under /etc/config)
local UCI_CONFIG_NAME = 'wifibox'
--- Absolute path to the UCI config file
local UCI_CONFIG_FILE = '/etc/config/' .. UCI_CONFIG_NAME
local UCI_CONFIG_TYPE = 'settings' -- the section type that will be used in UCI_CONFIG_FILE
local UCI_CONFIG_SECTION = 'general' -- the section name that will be used in UCI_CONFIG_FILE
--- Section type that will be used in UCI\_CONFIG\_FILE
local UCI_CONFIG_TYPE = 'settings'
--- Section name that will be used in UCI\_CONFIG\_FILE
local UCI_CONFIG_SECTION = 'general'
local ERR_NO_SUCH_KEY = "key does not exist"
--- Returns the given key with all periods ('.') replaced by underscores ('_').
-- @param key The key for which to substitute dots.
--- Returns a key with all periods ('.') replaced by underscores ('_').
-- @tparam string key The key for which to substitute dots.
-- @return The substituted key, or the key parameter itself if it is not of type 'string'.
local function replaceDots(key)
if type(key) ~= 'string' then return key end
@ -31,18 +41,33 @@ local function replaceDots(key)
return r
end
-- The inverse of replaceDots()
--- Returns a key with all underscores ('_') replaced by periods ('.').
-- @tparam string key The key for which to substitute underscores.
-- @return The substituted key, or the key parameter itself if it is not of type 'string'.
local function replaceUnderscores(key)
if type(key) ~= 'string' then return key end
local r = key:gsub('_', '%.')
return r
end
--- Converts a lua value to equivalent representation for UCI.
-- Boolean values are converted to '1' and '0', everything else is converted to a string.
--
-- @param v The value to convert.
-- @param vType The type of the given value.
-- @return A value usable to write to UCI.
local function toUciValue(v, vType)
if vType == 'bool' then return v and '1' or '0' end
return tostring(v)
end
--- Converts a value read from UCI to a correctly typed lua value.
-- For boolean, '1' is converted to true and everything else to false. Floats
-- and ints are converted to numbers and everything else will be returned as is.
--
-- @param v The value to convert.
-- @param vType The type of the given value.
-- @return A lua value typed correctly with regard to the vType parameter.
local function fromUciValue(v, vType)
if v == nil then return nil end
@ -56,6 +81,10 @@ local function fromUciValue(v, vType)
end
--- Reports whether a value is valid given the constraints specified in a base table.
-- @param value The value to test.
-- @tparam table baseTable The base table to use constraint data from (min,max,regex).
-- @treturn bool Returns true if the value is valid, false if it is not.
local function isValid(value, baseTable)
local varType, min, max, regex = baseTable.type, baseTable.min, baseTable.max, baseTable.regex
@ -81,6 +110,9 @@ local function isValid(value, baseTable)
return true
end
--- Looks up the table in conf_defaults.lua corresponding to a key.
-- @tparam string key The key for which to return the base table.
-- @treturn table The base table for key, or nil if it does not exist.
local function getBaseKeyTable(key)
local base = baseconfig[key]
return type(base) == 'table' and base.default ~= nil and base or nil
@ -105,6 +137,8 @@ function M.get(key)
return actualV
end
--- Returns all configuration keys with their current values.
-- @treturn table A table containing a key/value pair for each configuration key.
function M.getAll()
local result = {}
for k,_ in pairs(baseconfig) do
@ -116,18 +150,32 @@ function M.getAll()
return result
end
--- Reports whether or not a key exists.
-- @tparam string key The key to find.
-- @treturn bool True if the key exists, false if not.
function M.exists(key)
key = replaceDots(key)
return getBaseKeyTable(key) ~= nil
end
--- Reports whether or not a key is at its default value.
-- 'Default' in this regard means that no UCI value is defined. This means that
-- if for instance, the default is 'abc', and UCI contains a configured value of
-- 'abc' as well, that key is _not_ a default value.
--
-- @tparam string key The key to report about.
-- @treturn bool True if the key is currently at its default value, false if not.
function M.isDefault(key)
key = replaceDots(key)
if not M.exists(key) then return nil,ERR_NO_SUCH_KEY end
return uci:get(UCI_CONFIG_NAME, UCI_CONFIG_SECTION, key) == nil
end
-- pass nil as value to restore default
--- Sets a key to a new value or reverts it to the default value.
-- @tparam string key The key to set.
-- @param value The value or set, or nil to revert key to its default value.
-- @treturn bool|nil True if everything went well, nil in case of error.
-- @treturn ?string Error message in case first return value is nil (invalid key).
function M.set(key, value)
key = replaceDots(key)
local r = utils.create(UCI_CONFIG_FILE)
@ -139,6 +187,13 @@ function M.set(key, value)
if M.isDefault(key) and value == nil then return true end -- key is default already
local current = uci:get(UCI_CONFIG_NAME, UCI_CONFIG_SECTION, key)
-- TODO: test if this fixes setting bools (and does not break settings the other types)
-- if base.type == 'bool' then
-- value = utils.toboolean(value)
-- elseif base.type == 'int' or base.type == 'float' then
-- value = tonumber(value)
-- end
if fromUciValue(current, base.type) == value then return true end

13
src/util/utils.lua

@ -1,7 +1,11 @@
local uci = require('uci').cursor()
--[[--
TODO: finish documentation
The unavoidable collection of utility functions.
]]
local M = {}
function string:split(div)
local div, pos, arr = div or ':', 0, {}
for st,sp in function() return self:find(div, pos, true) end do
@ -42,7 +46,14 @@ function M.dump(o)
end
end
--- Returns the name of a section in a UCI config.
-- This name is necessary to be able to refer to the corresponding section and
-- the UCI library does not provide a way to look it up.
-- @tparam string config Name of the UCI config to search through.
-- @tparam string type UCI type of the section to find.
-- @treturn string Name of the section matching the parameters, or nil if it could not be found.
function M.getUciSectionName(config, type)
local uci = require('uci').cursor()
local sname = nil
uci:foreach(config, type, function(s) sname = s['.name'] end)
return sname

Loading…
Cancel
Save