Add luacheck config and configuration for Travis CI (#2790)

* Move luacheck conf and fix Travis for all possible filenames
* Add lua script to help with luacheck config
* Add xargs approach for current luac.cross file checking
* Enable luacheck but do not break build
This commit is contained in:
galjonsfigur 2019-06-28 06:53:19 +02:00 committed by Marcel Stör
parent 93b1a2dce9
commit 7de8a01705
6 changed files with 1164 additions and 3 deletions

View File

@ -30,6 +30,8 @@ script:
- if [ "$OS" = "windows" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/ci-build-windows-ms.sh; fi - if [ "$OS" = "windows" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/ci-build-windows-ms.sh; fi
- if [ "$OS" = "linux" -a "$TRAVIS_PULL_REQUEST" != "false" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/pr-build.sh; fi - if [ "$OS" = "linux" -a "$TRAVIS_PULL_REQUEST" != "false" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/pr-build.sh; fi
- cd "$TRAVIS_BUILD_DIR" - cd "$TRAVIS_BUILD_DIR"
- LUA_FILES=`find lua_modules lua_examples -iname "*.lua"` - echo "checking:"
- echo checking $LUA_FILES - find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 echo
- $LUACC -p $LUA_FILES - find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 $LUACC -p
- if [ "$OS" = "linux" ]; then bash "$TRAVIS_BUILD_DIR"/tools/travis/run-luacheck.sh || true ; fi

View File

@ -26,6 +26,13 @@ Use the platform and tools you feel most comfortable with. There are no constrai
- [Full-fledged Linux environment](http://www.esp8266.com/wiki/doku.php?id=toolchain#how_to_setup_a_vm_to_host_your_toolchain), either physical or virtual. - [Full-fledged Linux environment](http://www.esp8266.com/wiki/doku.php?id=toolchain#how_to_setup_a_vm_to_host_your_toolchain), either physical or virtual.
- [Docker image](https://hub.docker.com/r/marcelstoer/nodemcu-build/) which allows running the build inside the container as if you were running a build script on your local machine. - [Docker image](https://hub.docker.com/r/marcelstoer/nodemcu-build/) which allows running the build inside the container as if you were running a build script on your local machine.
## Writing Lua Code
A great resource about writing Lua for NodeMCU can be found in [Lua Developer FAQ](https://nodemcu.readthedocs.io/en/latest/lua-developer-faq/) - make sure to read it! When you're writing your Lua code and it's not working as it should you can test it with `luacheck` tool that can help you find various types of bugs. To install it you have to install [luarocks](https://luarocks.org/) and use command `sudo luarocks install luacheck` to install the tool. Now you're ready to go! By using this command (assuming you're in `nodemcu-firmware` directory):
`luacheck --config tools/luacheck_config.lua <your file to check>`
you can look for bugs and problems within the code!
## Writing Documentation ## Writing Documentation
The NodeMCU documentation is maintained within the same repository as the code. The primary reason is to keep the two in sync more easily. It's thus trivial for the NodeMCU team to verify that a PR includes the necessary documentation. Furthermore, the documentation is merged automatically with the code if it moves from branch X to Y. The NodeMCU documentation is maintained within the same repository as the code. The primary reason is to keep the two in sync more easily. It's thus trivial for the NodeMCU team to verify that a PR includes the necessary documentation. Furthermore, the documentation is merged automatically with the code if it moves from branch X to Y.

883
tools/luacheck_config.lua Normal file
View File

@ -0,0 +1,883 @@
local empty = { }
local read_write = {read_only = false}
stds.nodemcu_libs = {
read_globals = {
adc = {
fields = {
INIT_ADC = empty,
INIT_VDD33 = empty,
force_init_mode = empty,
read = empty,
readvdd33 = empty
}
},
ads1115 = {
fields = {
ADDR_GND = empty,
ADDR_SCL = empty,
ADDR_SDA = empty,
ADDR_VDD = empty,
CMODE_TRAD = empty,
CMODE_WINDOW = empty,
COMP_1CONV = empty,
COMP_2CONV = empty,
COMP_4CONV = empty,
CONTINUOUS = empty,
CONV_RDY_1 = empty,
CONV_RDY_2 = empty,
CONV_RDY_4 = empty,
DIFF_0_1 = empty,
DIFF_0_3 = empty,
DIFF_1_3 = empty,
DIFF_2_3 = empty,
DR_128SPS = empty,
DR_1600SPS = empty,
DR_16SPS = empty,
DR_2400SPS = empty,
DR_250SPS = empty,
DR_32SPS = empty,
DR_3300SPS = empty,
DR_475SPS = empty,
DR_490SPS = empty,
DR_64SPS = empty,
DR_860SPS = empty,
DR_8SPS = empty,
DR_920SPS = empty,
GAIN_0_256V = empty,
GAIN_0_512V = empty,
GAIN_1_024V = empty,
GAIN_2_048V = empty,
GAIN_4_096V = empty,
GAIN_6_144V = empty,
SINGLE_0 = empty,
SINGLE_1 = empty,
SINGLE_2 = empty,
SINGLE_3 = empty,
SINGLE_SHOT = empty,
ads1015 = empty,
ads1115 = empty,
read = empty,
reset = empty,
}
},
adxl345 = {
fields = {
read = empty,
setup = empty
}
},
am2320 = {
fields = {
read = empty,
setup = empty
}
},
apa102 = {
fields = {
write = empty
}
},
bit = {
fields = {
arshift = empty,
band = empty,
bit = empty,
bnot = empty,
bor = empty,
bxor = empty,
clear = empty,
isclear = empty,
isset = empty,
lshift = empty,
rshift = empty,
set = empty
}
},
bloom = {
fields = {
create = empty
}
},
bme280 = {
fields = {
altitude = empty,
baro = empty,
dewpoint = empty,
humi = empty,
qfe2qnh = empty,
read = empty,
setup = empty,
startreadout = empty,
temp = empty
}
},
bme680 = {
fields = {
altitude = empty,
dewpoint = empty,
qfe2qnh = empty,
read = empty,
setup = empty,
startreadout = empty
}
},
bmp085 = {
fields = {
pressure = empty,
pressure_raw = empty,
setup = empty,
temperature = empty
}
},
coap = {
fields = {
CON = empty,
Client = empty,
EXI = empty,
JSON = empty,
LINKFORMAT = empty,
NON = empty,
OCTET_STREAM = empty,
Server = empty,
TEXT_PLAIN = empty,
XML = empty
}
},
color_utils = {
fields = {
colorWheel = empty,
grb2hsv = empty,
hsv2grb = empty,
hsv2grbw = empty
}
},
cron = {
fields = {
reset = empty,
schedule = empty
}
},
crypto = {
fields = {
decrypt = empty,
encrypt = empty,
fhash = empty,
hash = empty,
hmac = empty,
mask = empty,
new_hash = empty,
new_hmac = empty,
sha1 = empty,
toBase64 = empty,
toHex = empty
}
},
dht = {
fields = {
ERROR_CHECKSUM = empty,
ERROR_TIMEOUT = empty,
OK = empty,
read = empty,
read11 = empty,
readxx = empty
}
},
encoder = {
fields = {
fromBase64 = empty,
fromHex = empty,
toBase64 = empty,
toHex = empty
}
},
enduser_setup = {
fields = {
manual = empty,
start = empty,
stop = empty
}
},
file = {
fields = {
close = empty,
exists = empty,
flush = empty,
fsinfo = empty,
getcontents = empty,
list = empty,
on = empty,
open = empty,
putcontents = empty,
read = empty,
readline = empty,
remove = empty,
rename = empty,
seek = empty,
stat = empty,
write = empty,
writeline = empty
}
},
gdbstub = {
fields = {
brk = empty,
gdboutput = empty,
open = empty
}
},
gpio = {
fields = {
FLOAT = empty,
HIGH = empty,
INPUT = empty,
INT = empty,
LOW = empty,
OPENDRAIN = empty,
OUTPUT = empty,
PULLUP = empty,
mode = empty,
read = empty,
serout = empty,
trig = empty,
write = empty,
pulse = {
fields = {
adjust = empty,
cancel = empty,
getstate = empty,
start = empty,
stop = empty,
update = empty
}
}
}
},
hdc1080 = {
fields = {
read = empty,
setup = empty
}
},
hmc5883 = {
fields = {
read = empty,
setup = empty
}
},
http = {
fields = {
ERROR = empty,
OK = empty,
delete = empty,
get = empty,
post = empty,
put = empty,
request = empty
}
},
hx711 = {
fields = {
init = empty,
read = empty
}
},
i2c = {
fields = {
FAST = empty,
FASTPLUS = empty,
RECEIVER = empty,
SLOW = empty,
TRANSMITTER = empty,
address = empty,
read = empty,
setup = empty,
start = empty,
stop = empty,
write = empty
}
},
l3g4200d = {
fields = {
read = empty,
setup = empty
}
},
mcp4725 = {
fields = {
PWRDN_100K = empty,
PWRDN_1K = empty,
PWRDN_500K = empty,
PWRDN_NONE = empty,
read = empty,
write = empty
}
},
mdns = {
fields = {
close = empty,
register = empty
}
},
mqtt = {
fields = {
CONNACK_ACCEPTED = empty,
CONNACK_REFUSED_BAD_USER_OR_PASS = empty,
CONNACK_REFUSED_ID_REJECTED = empty,
CONNACK_REFUSED_NOT_AUTHORIZED = empty,
CONNACK_REFUSED_PROTOCOL_VER = empty,
CONNACK_REFUSED_SERVER_UNAVAILABLE = empty,
CONN_FAIL_DNS = empty,
CONN_FAIL_NOT_A_CONNACK_MSG = empty,
CONN_FAIL_SERVER_NOT_FOUND = empty,
CONN_FAIL_TIMEOUT_RECEIVING = empty,
CONN_FAIL_TIMEOUT_SENDING = empty,
Client = empty
}
},
net = {
fields = {
TCP = empty,
UDP = empty,
cert = empty,
createConnection = empty,
createServer = empty,
createUDPSocket = empty,
dns = {
fields = {
getdnsserver = empty,
resolve = empty,
setdnsserver = empty
}
},
multicastJoin = empty,
multicastLeave = empty
}
},
node = {
fields = {
CPU160MHZ = empty,
CPU80MHZ = empty,
bootreason = empty,
chipid = empty,
compile = empty,
dsleep = empty,
dsleepMax = empty,
dsleepsetoption = empty,
flashid = empty,
flashindex = empty,
flashreload = empty,
flashsize = empty,
getcpufreq = empty,
getpartitiontable = empty,
heap = empty,
info = empty,
input = empty,
osprint = empty,
output = empty,
random = empty,
readrcr = empty,
readvdd33 = empty,
restart = empty,
restore = empty,
setcpufreq = empty,
setpartitiontable = empty,
sleep = empty,
stripdebug = empty,
writercr = empty,
egc = {
fields = {
setmode = empty,
meminfo = empty
}
},
task = {
fields = {
post = empty
}
}
}
},
ow = {
fields = {
check_crc16 = empty,
crc16 = empty,
crc8 = empty,
depower = empty,
read = empty,
read_bytes = empty,
reset = empty,
reset_search = empty,
search = empty,
select = empty,
setup = empty,
skip = empty,
target_search = empty,
write = empty,
write_bytes = empty
}
},
pcm = {
fields = {
RATE_10K = empty,
RATE_12K = empty,
RATE_16K = empty,
RATE_1K = empty,
RATE_2K = empty,
RATE_4K = empty,
RATE_5K = empty,
RATE_8K = empty,
SD = empty,
new = empty
}
},
pwm = {
fields = {
close = empty,
getclock = empty,
getduty = empty,
setclock = empty,
setduty = empty,
setup = empty,
start = empty,
stop = empty
}
},
pwm2 = {
fields = {
get_pin_data = empty,
get_timer_data = empty,
release_pin = empty,
set_duty = empty,
setup_pin_hz = empty,
setup_pin_sec = empty,
start = empty,
stop = empty,
}
},
rc = {
fields = {
send = empty
}
},
rfswitch = {
fields = {
send = empty
}
},
rotary = {
fields = {
ALL = empty,
CLICK = empty,
DBLCLICK = empty,
LONGPRESS = empty,
PRESS = empty,
RELEASE = empty,
TURN = empty,
close = empty,
getpos = empty,
on = empty,
setup = empty
}
},
rtcfifo = {
fields = {
count = empty,
drop = empty,
dsleep_until_sample = empty,
peek = empty,
pop = empty,
prepare = empty,
put = empty,
ready = empty
}
},
rtcmem = {
fields = {
read32 = empty,
write32 = empty
}
},
rtctime = {
fields = {
adjust_delta = empty,
dsleep = empty,
dsleep_aligned = empty,
epoch2cal = empty,
get = empty,
set = empty
}
},
si7021 = {
fields = {
HEATER_DISABLE = empty,
HEATER_ENABLE = empty,
RH08_TEMP12 = empty,
RH10_TEMP13 = empty,
RH11_TEMP11 = empty,
RH12_TEMP14 = empty,
firmware = empty,
read = empty,
serial = empty,
setting = empty,
setup = empty
}
},
sigma_delta = {
fields = {
close = empty,
setprescale = empty,
setpwmduty = empty,
settarget = empty,
setup = empty
}
},
sjson = {
fields = {
decode = empty,
decoder = empty,
encode = empty,
encoder = empty
}
},
sntp = {
fields = {
getoffset = empty,
setoffset = empty,
sync = empty
}
},
somfy = {
fields = {
DOWN = empty,
PROG = empty,
STOP = empty,
UP = empty,
sendcommand = empty
}
},
spi = {
fields = {
CPHA_HIGH = empty,
CPHA_LOW = empty,
CPOL_HIGH = empty,
CPOL_LOW = empty,
DATABITS_8 = empty,
FULLDUPLEX = empty,
HALFDUPLEX = empty,
MASTER = empty,
SLAVE = empty,
get_miso = empty,
recv = empty,
send = empty,
set_clock_div = empty,
set_mosi = empty,
setup = empty,
transaction = empty
}
},
switec = {
fields = {
close = empty,
dequeue = empty,
getpos = empty,
moveto = empty,
reset = empty,
setup = empty
}
},
tcs34725 = {
fields = {
disable = empty,
enable = empty,
raw = empty,
setGain = empty,
setIntegrationTime = empty,
setup = empty
}
},
tls = {
fields = {
createConnection = empty,
setDebug = empty,
cert = {
fields = {
auth = empty,
verify = empty
}
}
}
},
tm1829 = {
fields = {
write = empty
}
},
tmr = {
fields = {
ALARM_AUTO = empty,
ALARM_SEMI = empty,
ALARM_SINGLE = empty,
create = empty,
delay = empty,
now = empty,
resume_all = empty,
softwd = empty,
suspend_all = empty,
time = empty,
wdclr = empty
}
},
tsl2561 = {
fields = {
ADDRESS_FLOAT = empty,
ADDRESS_GND = empty,
ADDRESS_VDD = empty,
GAIN_16X = empty,
GAIN_1X = empty,
INTEGRATIONTIME_101MS = empty,
INTEGRATIONTIME_13MS = empty,
INTEGRATIONTIME_402MS = empty,
PACKAGE_CS = empty,
PACKAGE_T_FN_CL = empty,
TSL2561_ERROR_I2CBUSY = empty,
TSL2561_ERROR_I2CINIT = empty,
TSL2561_ERROR_LAST = empty,
TSL2561_ERROR_NOINIT = empty,
TSL2561_OK = empty,
getlux = empty,
getrawchannels = empty,
init = empty,
settiming = empty
}
},
-- There would be too many fields for all the fonts and displays
u8g2 = {other_fields = true},
uart = {
fields = {
PARITY_EVEN = empty,
PARITY_NONE = empty,
PARITY_ODD = empty,
STOPBITS_1 = empty,
STOPBITS_1_5 = empty,
STOPBITS_2 = empty,
alt = empty,
getconfig = empty,
on = empty,
setup = empty,
write = empty
}
},
-- There would be too many fields for all the fonts and displays
ucg = {other_fields = true},
websocket = {
fields = {
createClient = empty
}
},
wifi = {
fields = {
COUNTRY_AUTO = empty,
COUNTRY_MANUAL = empty,
LIGHT_SLEEP = empty,
MODEM_SLEEP = empty,
NONE_SLEEP = empty,
NULLMODE = empty,
OPEN = empty,
PHYMODE_B = empty,
PHYMODE_G = empty,
PHYMODE_N = empty,
SOFTAP = empty,
STATION = empty,
STATIONAP = empty,
STA_APNOTFOUND = empty,
STA_CONNECTING = empty,
STA_FAIL = empty,
STA_GOTIP = empty,
STA_IDLE = empty,
STA_WRONGPWD = empty,
WEP = empty,
WPA2_PSK = empty,
WPA_PSK = empty,
WPA_WPA2_PSK = empty,
getchannel = empty,
getcountry = empty,
getdefaultmode = empty,
getmode = empty,
getphymode = empty,
nullmodesleep = empty,
resume = empty,
setcountry = empty,
setmaxtxpower = empty,
setmode = empty,
setphymode = empty,
sleeptype = empty,
startsmart = empty,
stopsmart = empty,
suspend = empty,
sta = {
fields = {
autoconnect = empty,
changeap = empty,
clearconfig = empty,
config = empty,
connect = empty,
disconnect = empty,
getap = empty,
getapindex = empty,
getapinfo = empty,
getbroadcast = empty,
getconfig = empty,
getdefaultconfig = empty,
gethostname = empty,
getip = empty,
getmac = empty,
getrssi = empty,
setaplimit = empty,
sethostname = empty,
setip = empty,
setmac = empty,
sleeptype = empty,
status = empty
}
},
ap = {
fields = {
config = empty,
deauth = empty,
getbroadcast = empty,
getclient = empty,
getconfig = empty,
getdefaultconfig = empty,
getip = empty,
getmac = empty,
setip = empty,
setmac = empty,
dhcp = {
fields = {
config = empty,
start = empty,
stop = empty
}
},
}
},
eventmon = {
fields = {
AP_PROBEREQRECVED = empty,
AP_STACONNECTED = empty,
AP_STADISCONNECTED = empty,
EVENT_MAX = empty,
STA_AUTHMODE_CHANGE = empty,
STA_CONNECTED = empty,
STA_DHCP_TIMEOUT = empty,
STA_DISCONNECTED = empty,
STA_GOT_IP = empty,
WIFI_MODE_CHANGED = empty,
register = empty,
unregister = empty,
reason = {
fields = {
["4WAY_HANDSHAKE_TIMEOUT"] = empty,
["802_1X_AUTH_FAILED"] = empty,
AKMP_INVALID = empty,
ASSOC_EXPIRE = empty,
ASSOC_FAIL = empty,
ASSOC_LEAVE = empty,
ASSOC_NOT_AUTHED = empty,
ASSOC_TOOMANY = empty,
AUTH_EXPIRE = empty,
AUTH_FAIL = empty,
AUTH_LEAVE = empty,
BEACON_TIMEOUT = empty,
CIPHER_SUITE_REJECTED = empty,
DISASSOC_PWRCAP_BAD = empty,
DISASSOC_SUPCHAN_BAD = empty,
GROUP_CIPHER_INVALID = empty,
GROUP_KEY_UPDATE_TIMEOUT = empty,
HANDSHAKE_TIMEOUT = empty,
IE_INVALID = empty,
IE_IN_4WAY_DIFFERS = empty,
INVALID_RSN_IE_CAP = empty,
MIC_FAILURE = empty,
NOT_ASSOCED = empty,
NOT_AUTHED = empty,
NO_AP_FOUND = empty,
PAIRWISE_CIPHER_INVALID = empty,
UNSPECIFIED = empty,
UNSUPP_RSN_IE_VERSION = empty
}
}
}
},
monitor = {
fields = {
channel = empty,
start = empty,
stop = empty
}
}
}
},
wps = {
fields = {
FAILED = empty,
SCAN_ERR = empty,
SUCCESS = empty,
TIMEOUT = empty,
WEP = empty,
disable = empty,
enable = empty,
start = empty
}
},
ws2801 = {
fields = {
init = empty,
write = empty
}
},
ws2812 = {
fields = {
FADE_IN = empty,
FADE_OUT = empty,
MODE_DUAL = empty,
MODE_SINGLE = empty,
SHIFT_CIRCULAR = empty,
SHIFT_LOGICAL = empty,
init = empty,
newBuffer = empty,
write = empty
}
},
ws2812_effects = {
fields = {
get_delay = empty,
get_speed = empty,
init = empty,
set_brightness = empty,
set_color = empty,
set_delay = empty,
set_mode = empty,
set_speed = empty,
start = empty,
stop = empty
}
},
xpt2046 = {
fields = {
getPosition = empty,
getPositionAvg = empty,
getRaw = empty,
init = empty,
isTouched = empty,
setCalibration = empty
}
},
pack = empty,
unpack = empty,
size = empty
}
}
std = "lua51+nodemcu_libs"

139
tools/luacheck_config_helper.lua Executable file
View File

@ -0,0 +1,139 @@
#!/usr/bin/lua
---
-- Script to extract names and the functions themselves from NodeMCU modules and
-- to help creating luacheck configuration.
-- Usage: <in modules catalog> ../../tools/luacheck_config_helper.lua *.c (or filename for single module)
local M = {}
-- Recursive object dumper, for debugging.
-- (c) 2010 David Manura, MIT License.
-- From: https://github.com/davidm/lua-inspect/blob/master/lib/luainspect/dump.lua
local ignore_keys_ = {lineinfo = true}
local norecurse_keys_ = {parent = true, ast = true}
local function dumpstring_key_(k, isseen, newindent)
local ks = type(k) == 'string' and k:match'^[%a_][%w_]*$' and k or
'[' .. M.dumpstring(k, isseen, newindent) .. ']'
return ks
end
local function sort_keys_(a, b)
if type(a) == 'number' and type(b) == 'number' then
return a < b
elseif type(a) == 'number' then
return false
elseif type(b) == 'number' then
return true
elseif type(a) == 'string' and type(b) == 'string' then
return a < b
else
return tostring(a) < tostring(b) -- arbitrary
end
end
function M.dumpstring(o, isseen, indent, key)
isseen = isseen or {}
indent = indent or ''
if type(o) == 'table' then
if isseen[o] or norecurse_keys_[key] then
return (type(o.tag) == 'string' and '`' .. o.tag .. ':' or '') .. tostring(o)
else isseen[o] = true end -- avoid recursion
local used = {}
local tag = o.tag
local s = '{'
if type(o.tag) == 'string' then
s = '`' .. tag .. s; used['tag'] = true
end
local newindent = indent .. ' '
local ks = {}; for k in pairs(o) do ks[#ks+1] = k end
table.sort(ks, sort_keys_)
local forcenummultiline
for k in pairs(o) do
if type(k) == 'number' and type(o[k]) == 'table' then forcenummultiline = true end
end
-- inline elements
for _,k in ipairs(ks) do
if ignore_keys_[k] then used[k] = true
elseif (type(k) ~= 'number' or not forcenummultiline) and
type(k) ~= 'table' and (type(o[k]) ~= 'table' or norecurse_keys_[k])
then
s = s .. dumpstring_key_(k, isseen, newindent) .. ' = ' .. M.dumpstring(o[k], isseen, newindent, k) .. ', '
used[k] = true
end
end
-- elements on separate lines
local done
for _,k in ipairs(ks) do
if not used[k] then
if not done then s = s .. '\n'; done = true end
s = s .. newindent .. dumpstring_key_(k, isseen) .. ' = ' .. M.dumpstring(o[k], isseen, newindent, k) .. ',\n'
end
end
s = s:gsub(',(%s*)$', '%1')
s = s .. (done and indent or '') .. '}'
return s
elseif type(o) == 'string' then
return string.format('%q', o)
else
return tostring(o)
end
end
-- End of dump.lua code
local function printTables(fileName)
local findBegin, field
if type(fileName) ~= "string" then error("Wrong argument") end
local file = io.open(fileName, "r")
if not file then error("Can't open file") end
local result = {}
result.fields = {}
for line in file:lines() do
findBegin, _, field = string.find(line, "LROT_BEGIN%((%g+)%)")
if findBegin then
io.write(field.." = ")
end
findBegin, _, field = string.find(line, "LROT_PUBLIC_BEGIN%((%g+)%)")
if findBegin then
print(field.." = ")
end
findBegin, _, field = string.find(line, "LROT_FUNCENTRY%(%s?(%g+),")
if not findBegin then
findBegin, _, field = string.find(line, "LROT_NUMENTRY%(%s?(%g+),")
end
if not findBegin then
findBegin, _, field = string.find(line, "LROT_TABENTRY%(%s?(%g+),")
end
if findBegin then
if not string.find(field, "__") then
result.fields[field] = {}
end
end
findBegin = string.find(line, "LROT_END")
if findBegin then
print(string.gsub(M.dumpstring(result), "{}", "empty")..',')
result = {}
result.fields = {}
end
end
end
local function main()
for i = 1, #arg do
printTables(arg[i])
end
end
main()

113
tools/travis/localua.sh Executable file
View File

@ -0,0 +1,113 @@
#!/bin/bash
# Downloads and installs a self-contained Lua and LuaRocks.
# Supports Linux, macOS and MSYS2.
# Copyright (c) 2015-2019 Pierre Chapuis, MIT Licensed.
# Latest stable version available at: https://loadk.com/localua.sh
# Maintained at: https://github.com/oploadk/localua
DEFAULT_LUA_V="5.3.5"
DEFAULT_LR_V="3.0.4"
usage () {
>&2 echo -e "USAGE: $0 output-dir [lua-version] [luarocks-version]\n"
>&2 echo -n "The first optional argument is the Lua version, "
>&2 echo -n "the second one is the LuaRocks version. "
>&2 echo -e "Defaults are Lua $DEFAULT_LUA_V and LuaRocks $DEFAULT_LR_V.\n"
>&2 echo -n "You can set a custom build directory with environment "
>&2 echo -e "variable LOCALUA_BUILD_DIRECTORY (not useful in general).\n"
>&2 echo -e "You can set a custom makefile target with LOCALUA_TARGET.\n"
>&2 echo -e "You can disable LUA_COMPAT by setting LOCALUA_NO_COMPAT.\n"
>&2 echo -e "You can skip luarocks by setting LOCALUA_NO_LUAROCKS."
exit 1
}
# Set output directory, Lua version and LuaRocks version
ODIR="$1"
[ -z "$ODIR" ] && usage
LUA_V="$2"
[ -z "$LUA_V" ] && LUA_V="$DEFAULT_LUA_V"
LUA_SHORTV="$(echo $LUA_V | cut -c 1-3)"
LR_V="$3"
[ -z "$LR_V" ] && LR_V="$DEFAULT_LR_V"
# Set build directory
BDIR="$LOCALUA_BUILD_DIRECTORY"
[ -z "$BDIR" ] && BDIR="$(mktemp -d /tmp/localua-XXXXXX)"
# Create output directory and get absolute path
mkdir -p "$ODIR"
>/dev/null pushd "$ODIR"
ODIR="$(pwd)"
>/dev/null popd
# Download, unpack and build Lua and LuaRocks
if [ -z "$LOCALUA_TARGET" ]; then
case "$(uname)" in
Linux)
LOCALUA_TARGET="linux";;
Darwin)
LOCALUA_TARGET="macosx";;
MSYS*)
LOCALUA_TARGET="msys";;
*)
LOCALUA_TARGET="posix";;
esac
fi
pushd "$BDIR"
wget "http://www.lua.org/ftp/lua-${LUA_V}.tar.gz"
tar xf "lua-${LUA_V}.tar.gz"
pushd "lua-${LUA_V}"
sed 's#"/usr/local/"#"'"$ODIR"'/"#' "src/luaconf.h" > "$BDIR/t"
mv "$BDIR/t" "src/luaconf.h"
if [ ! -z "$LOCALUA_NO_COMPAT" ]; then
sed 's#-DLUA_COMPAT_5_2##' "src/Makefile" > "$BDIR/t"
sed 's#-DLUA_COMPAT_ALL##' "$BDIR/t" > "src/Makefile"
fi
if [ "$LOCALUA_TARGET" = "msys" ]; then
>> "src/Makefile" echo
>> "src/Makefile" echo 'msys:' >> "src/Makefile"
>> "src/Makefile" echo -ne "\t"
>> "src/Makefile" echo '$(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \'
>> "src/Makefile" echo -ne "\t"
>> "src/Makefile" echo '"AR=$(CC) -shared -Wl,--out-implib,liblua.dll.a -o" "RANLIB=strip --strip-unneeded" \'
>> "src/Makefile" echo -ne "\t"
>> "src/Makefile" echo '"SYSCFLAGS=-DLUA_BUILD_AS_DLL -DLUA_USE_POSIX -DLUA_USE_DLOPEN" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe'
>> "src/Makefile" echo -ne "\t"
>> "src/Makefile" echo '$(MAKE) "LUAC_T=luac.exe" luac.exe'
make -C src "$LOCALUA_TARGET" || exit 1
make \
TO_BIN="lua.exe luac.exe lua53.dll" \
TO_LIB="liblua.a liblua.dll.a" \
INSTALL_TOP="$ODIR" install || exit 1
else
make "$LOCALUA_TARGET" || exit 1
make INSTALL_TOP="$ODIR" install || exit 1
fi
popd
if [ -z "$LOCALUA_NO_LUAROCKS" ]; then
wget "http://luarocks.org/releases/luarocks-${LR_V}.tar.gz"
tar xf "luarocks-${LR_V}.tar.gz"
pushd "luarocks-${LR_V}"
./configure --with-lua="$ODIR" --prefix="$ODIR" \
--lua-version="$LUA_SHORTV" \
--sysconfdir="$ODIR/luarocks" --force-config
make bootstrap
popd
fi
popd
# Cleanup
rm -rf "$BDIR"

View File

@ -0,0 +1,17 @@
#!/bin/bash
set -e
echo "Installing Lua 5.3, LuaRocks and Luacheck"
(
cd "$TRAVIS_BUILD_DIR" || exit
bash tools/travis/localua.sh cache/localua || exit
cache/localua/bin/luarocks install luacheck || exit
)
(
echo "Static analysys of:"
find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 echo
)
(find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 cache/localua/bin/luacheck --config tools/luacheck_config.lua) || exit