luacheck_config_helper.lua 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #!/usr/bin/lua
  2. ---
  3. -- Script to extract names and the functions themselves from NodeMCU modules and
  4. -- to help creating luacheck configuration.
  5. -- Usage: <in modules catalog> ../../tools/luacheck_config_helper.lua *.c (or filename for single module)
  6. local M = {}
  7. -- Recursive object dumper, for debugging.
  8. -- (c) 2010 David Manura, MIT License.
  9. -- From: https://github.com/davidm/lua-inspect/blob/master/lib/luainspect/dump.lua
  10. local ignore_keys_ = {lineinfo = true}
  11. local norecurse_keys_ = {parent = true, ast = true}
  12. local function dumpstring_key_(k, isseen, newindent)
  13. local ks = type(k) == 'string' and k:match'^[%a_][%w_]*$' and k or
  14. '[' .. M.dumpstring(k, isseen, newindent) .. ']'
  15. return ks
  16. end
  17. local function sort_keys_(a, b)
  18. if type(a) == 'number' and type(b) == 'number' then
  19. return a < b
  20. elseif type(a) == 'number' then
  21. return false
  22. elseif type(b) == 'number' then
  23. return true
  24. elseif type(a) == 'string' and type(b) == 'string' then
  25. return a < b
  26. else
  27. return tostring(a) < tostring(b) -- arbitrary
  28. end
  29. end
  30. function M.dumpstring(o, isseen, indent, key)
  31. isseen = isseen or {}
  32. indent = indent or ''
  33. if type(o) == 'table' then
  34. if isseen[o] or norecurse_keys_[key] then
  35. return (type(o.tag) == 'string' and '`' .. o.tag .. ':' or '') .. tostring(o)
  36. else isseen[o] = true end -- avoid recursion
  37. local used = {}
  38. local tag = o.tag
  39. local s = '{'
  40. if type(o.tag) == 'string' then
  41. s = '`' .. tag .. s; used['tag'] = true
  42. end
  43. local newindent = indent .. ' '
  44. local ks = {}; for k in pairs(o) do ks[#ks+1] = k end
  45. table.sort(ks, sort_keys_)
  46. local forcenummultiline
  47. for k in pairs(o) do
  48. if type(k) == 'number' and type(o[k]) == 'table' then forcenummultiline = true end
  49. end
  50. -- inline elements
  51. for _,k in ipairs(ks) do
  52. if ignore_keys_[k] then used[k] = true
  53. elseif (type(k) ~= 'number' or not forcenummultiline) and
  54. type(k) ~= 'table' and (type(o[k]) ~= 'table' or norecurse_keys_[k])
  55. then
  56. s = s .. dumpstring_key_(k, isseen, newindent) .. ' = ' .. M.dumpstring(o[k], isseen, newindent, k) .. ', '
  57. used[k] = true
  58. end
  59. end
  60. -- elements on separate lines
  61. local done
  62. for _,k in ipairs(ks) do
  63. if not used[k] then
  64. if not done then s = s .. '\n'; done = true end
  65. s = s .. newindent .. dumpstring_key_(k, isseen) .. ' = ' .. M.dumpstring(o[k], isseen, newindent, k) .. ',\n'
  66. end
  67. end
  68. s = s:gsub(',(%s*)$', '%1')
  69. s = s .. (done and indent or '') .. '}'
  70. return s
  71. elseif type(o) == 'string' then
  72. return string.format('%q', o)
  73. else
  74. return tostring(o)
  75. end
  76. end
  77. -- End of dump.lua code
  78. local function printTables(fileName)
  79. local findBegin, field
  80. if type(fileName) ~= "string" then error("Wrong argument") end
  81. local file = io.open(fileName, "r")
  82. if not file then error("Can't open file") end
  83. local result = {}
  84. result.fields = {}
  85. for line in file:lines() do
  86. findBegin, _, field = string.find(line, "LROT_BEGIN%((%g+)%)")
  87. if findBegin then
  88. io.write(field.." = ")
  89. end
  90. findBegin, _, field = string.find(line, "LROT_PUBLIC_BEGIN%((%g+)%)")
  91. if findBegin then
  92. print(field.." = ")
  93. end
  94. findBegin, _, field = string.find(line, "LROT_FUNCENTRY%(%s?(%g+),")
  95. if not findBegin then
  96. findBegin, _, field = string.find(line, "LROT_NUMENTRY%(%s?(%g+),")
  97. end
  98. if not findBegin then
  99. findBegin, _, field = string.find(line, "LROT_TABENTRY%(%s?(%g+),")
  100. end
  101. if not findBegin then
  102. findBegin, _, field = string.find(line, "LROT_FUNCENTRY_S%(%s?(%g+),")
  103. end
  104. if not findBegin then
  105. findBegin, _, field = string.find(line, "LROT_FUNCENTRY_F%(%s?(%g+),")
  106. end
  107. if findBegin then
  108. if not string.find(field, "__") then
  109. result.fields[field] = {}
  110. end
  111. end
  112. findBegin = string.find(line, "LROT_END")
  113. if findBegin then
  114. print(string.gsub(M.dumpstring(result), "{}", "empty")..',')
  115. result = {}
  116. result.fields = {}
  117. end
  118. end
  119. end
  120. local function main()
  121. for i = 1, #arg do
  122. printTables(arg[i])
  123. end
  124. end
  125. main()