subrepo:
  subdir:   "vendor/lite"
  merged:   "2783adc"
upstream:
  origin:   "https://github.com/jeremypenner/lite.git"
  branch:   "master"
  commit:   "2783adc"
git-subrepo:
  version:  "0.4.2"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "65fde50"
This commit is contained in:
Jeremy Penner 2020-11-19 15:40:36 -05:00
parent dab1881d90
commit 3d52b70bbc
493 changed files with 148088 additions and 0 deletions

3
vendor/lite/.gitattributes vendored Normal file
View file

@ -0,0 +1,3 @@
winlib/* linguist-vendored
src/lib/* linguist-vendored
icon.inl linguist-vendored

3
vendor/lite/.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1,3 @@
# These are supported funding model platforms
github: rxi

12
vendor/lite/.gitrepo vendored Normal file
View file

@ -0,0 +1,12 @@
; DO NOT EDIT (unless you know what you are doing)
;
; This subdirectory is a git "subrepo", and this file is maintained by the
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
;
[subrepo]
remote = https://github.com/jeremypenner/lite.git
branch = master
commit = 2783adc10c2f42beefdbc7f19cec8971e4e9bb80
parent = dab1881d90ab1514301a081a9dbc265325672b20
method = merge
cmdver = 0.4.2

19
vendor/lite/LICENSE vendored Normal file
View file

@ -0,0 +1,19 @@
Copyright (c) 2020 rxi
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

53
vendor/lite/README.md vendored Normal file
View file

@ -0,0 +1,53 @@
# lite-hearted
lite-hearted is a small compatibility shim for the lite text editor that allows
it to run in love2d. It is a quick-and-dirty experiment in embedding editing tools
into a game engine, to allow for building smooth game development workflows. It's
also literally a two-evening hack, so you will probably run into some rough edges!
You can run it simply by cloning this repo and running `love .`. Due to the
limitations of love2d's sandboxed filesystem, you can only edit files that are in
the project itself. Given the goals of this project, this should be fine.
Original README follows:
# lite
![screenshot](https://user-images.githubusercontent.com/3920290/81471642-6c165880-91ea-11ea-8cd1-fae7ae8f0bc4.png)
A lightweight text editor written in Lua
* **[Get lite](https://github.com/rxi/lite/releases/latest)** — Download
for Windows and Linux
* **[Get started](doc/usage.md)** — A quick overview on how to get started
* **[Get plugins](https://github.com/rxi/lite-plugins)** — Add additional
functionality
* **[Get color themes](https://github.com/rxi/lite-colors)** — Add additional colors
themes
## Overview
lite is a lightweight text editor written mostly in Lua — it aims to provide
something practical, pretty, *small* and fast, implemented as simply as
possible; easy to modify and extend, or to use without doing either.
## Customization
Additional functionality can be added through plugins which are available from
the [plugins repository](https://github.com/rxi/lite-plugins); additional color
themes can be found in the [colors repository](https://github.com/rxi/lite-colors).
The editor can be customized by making changes to the
[user module](data/user/init.lua).
## Building
You can build the project yourself on Linux using the provided `build.sh`
script. Note that the project does not need to be rebuilt if you are only making
changes to the Lua portion of the code.
## Contributing
Any additional functionality that can be added through a plugin should be done
so as a plugin, after which a pull request to the
[plugins repository](https://github.com/rxi/lite-plugins) can be made. In hopes
of remaining lightweight, pull requests adding additional functionality to the
core will likely not be merged. Bug reports and bug fixes are welcome.
## License
This project is free software; you can redistribute it and/or modify it under
the terms of the MIT license. See [LICENSE](LICENSE) for details.

43
vendor/lite/build.sh vendored Executable file
View file

@ -0,0 +1,43 @@
#!/bin/bash
cflags="-Wall -O3 -g -std=gnu11 -fno-strict-aliasing -Isrc"
lflags="-lSDL2 -lm"
if [[ $* == *windows* ]]; then
platform="windows"
outfile="lite.exe"
compiler="x86_64-w64-mingw32-gcc"
cflags="$cflags -DLUA_USE_POPEN -Iwinlib/SDL2-2.0.10/x86_64-w64-mingw32/include"
lflags="$lflags -Lwinlib/SDL2-2.0.10/x86_64-w64-mingw32/lib"
lflags="-lmingw32 -lSDL2main $lflags -mwindows -o $outfile res.res"
x86_64-w64-mingw32-windres res.rc -O coff -o res.res
else
platform="unix"
outfile="lite"
compiler="gcc"
cflags="$cflags -DLUA_USE_POSIX"
lflags="$lflags -o $outfile"
fi
if command -v ccache >/dev/null; then
compiler="ccache $compiler"
fi
echo "compiling ($platform)..."
for f in `find src -name "*.c"`; do
$compiler -c $cflags $f -o "${f//\//_}.o"
if [[ $? -ne 0 ]]; then
got_error=true
fi
done
if [[ ! $got_error ]]; then
echo "linking..."
$compiler *.o $lflags
fi
echo "cleaning up..."
rm *.o
rm res.res 2>/dev/null
echo "done"

10
vendor/lite/build_release.sh vendored Executable file
View file

@ -0,0 +1,10 @@
#!/bin/bash
./build.sh release windows
./build.sh release
rm lite.zip 2>/dev/null
cp winlib/SDL2-2.0.10/x86_64-w64-mingw32/bin/SDL2.dll SDL2.dll
strip lite
strip lite.exe
strip SDL2.dll
zip lite.zip lite lite.exe SDL2.dll data -r

6
vendor/lite/conf.lua vendored Normal file
View file

@ -0,0 +1,6 @@
function love.conf(t)
t.window.width = 1280
t.window.height = 1000
t.window.resizable = true
end

69
vendor/lite/data/core/command.lua vendored Normal file
View file

@ -0,0 +1,69 @@
local core = require "core"
local command = {}
command.map = {}
local always_true = function() return true end
function command.add(predicate, map)
predicate = predicate or always_true
if type(predicate) == "string" then
predicate = require(predicate)
end
if type(predicate) == "table" then
local class = predicate
predicate = function() return core.active_view:is(class) end
end
for name, fn in pairs(map) do
assert(not command.map[name], "command already exists: " .. name)
command.map[name] = { predicate = predicate, perform = fn }
end
end
local function capitalize_first(str)
return str:sub(1, 1):upper() .. str:sub(2)
end
function command.prettify_name(name)
return name:gsub(":", ": "):gsub("-", " "):gsub("%S+", capitalize_first)
end
function command.get_all_valid()
local res = {}
for name, cmd in pairs(command.map) do
if cmd.predicate() then
table.insert(res, name)
end
end
return res
end
local function perform(name)
local cmd = command.map[name]
if cmd and cmd.predicate() then
cmd.perform()
return true
end
return false
end
function command.perform(...)
local ok, res = core.try(perform, ...)
return not ok or res
end
function command.add_defaults()
local reg = { "core", "root", "command", "doc", "findreplace" }
for _, name in ipairs(reg) do
require("core.commands." .. name)
end
end
return command

View file

@ -0,0 +1,30 @@
local core = require "core"
local command = require "core.command"
local CommandView = require "core.commandview"
local function has_commandview()
return core.active_view:is(CommandView)
end
command.add(has_commandview, {
["command:submit"] = function()
core.active_view:submit()
end,
["command:complete"] = function()
core.active_view:complete()
end,
["command:escape"] = function()
core.active_view:exit()
end,
["command:select-previous"] = function()
core.active_view:move_suggestion_idx(1)
end,
["command:select-next"] = function()
core.active_view:move_suggestion_idx(-1)
end,
})

101
vendor/lite/data/core/commands/core.lua vendored Normal file
View file

@ -0,0 +1,101 @@
local core = require "core"
local common = require "core.common"
local command = require "core.command"
local keymap = require "core.keymap"
local LogView = require "core.logview"
local fullscreen = false
command.add(nil, {
["core:quit"] = function()
core.quit()
end,
["core:force-quit"] = function()
core.quit(true)
end,
["core:toggle-fullscreen"] = function()
fullscreen = not fullscreen
system.set_window_mode(fullscreen and "fullscreen" or "normal")
end,
["core:reload-module"] = function()
core.command_view:enter("Reload Module", function(text, item)
local text = item and item.text or text
core.reload_module(text)
core.log("Reloaded module %q", text)
end, function(text)
local items = {}
for name in pairs(package.loaded) do
table.insert(items, name)
end
return common.fuzzy_match(items, text)
end)
end,
["core:find-command"] = function()
local commands = command.get_all_valid()
core.command_view:enter("Do Command", function(text, item)
if item then
command.perform(item.command)
end
end, function(text)
local res = common.fuzzy_match(commands, text)
for i, name in ipairs(res) do
res[i] = {
text = command.prettify_name(name),
info = keymap.get_binding(name),
command = name,
}
end
return res
end)
end,
["core:find-file"] = function()
core.command_view:enter("Open File From Project", function(text, item)
text = item and item.text or text
core.root_view:open_doc(core.open_doc(text))
end, function(text)
local files = {}
for _, item in pairs(core.project_files) do
if item.type == "file" then
table.insert(files, item.filename)
end
end
return common.fuzzy_match(files, text)
end)
end,
["core:new-doc"] = function()
core.root_view:open_doc(core.open_doc())
end,
["core:open-file"] = function()
core.command_view:enter("Open File", function(text)
core.root_view:open_doc(core.open_doc(text))
end, common.path_suggest)
end,
["core:open-log"] = function()
local node = core.root_view:get_active_node()
node:add_view(LogView())
end,
["core:open-user-module"] = function()
core.root_view:open_doc(core.open_doc(EXEDIR .. "/data/user/init.lua"))
end,
["core:open-project-module"] = function()
local filename = ".lite_project.lua"
if system.get_file_info(filename) then
core.root_view:open_doc(core.open_doc(filename))
else
local doc = core.open_doc()
core.root_view:open_doc(doc)
doc:save(filename)
end
end,
})

363
vendor/lite/data/core/commands/doc.lua vendored Normal file
View file

@ -0,0 +1,363 @@
local core = require "core"
local command = require "core.command"
local common = require "core.common"
local config = require "core.config"
local translate = require "core.doc.translate"
local DocView = require "core.docview"
local function dv()
return core.active_view
end
local function doc()
return core.active_view.doc
end
local function get_indent_string()
if config.tab_type == "hard" then
return "\t"
end
return string.rep(" ", config.indent_size)
end
local function insert_at_start_of_selected_lines(text, skip_empty)
local line1, col1, line2, col2, swap = doc():get_selection(true)
for line = line1, line2 do
local line_text = doc().lines[line]
if (not skip_empty or line_text:find("%S")) then
doc():insert(line, 1, text)
end
end
doc():set_selection(line1, col1 + #text, line2, col2 + #text, swap)
end
local function remove_from_start_of_selected_lines(text, skip_empty)
local line1, col1, line2, col2, swap = doc():get_selection(true)
for line = line1, line2 do
local line_text = doc().lines[line]
if line_text:sub(1, #text) == text
and (not skip_empty or line_text:find("%S"))
then
doc():remove(line, 1, line, #text + 1)
end
end
doc():set_selection(line1, col1 - #text, line2, col2 - #text, swap)
end
local function append_line_if_last_line(line)
if line >= #doc().lines then
doc():insert(line, math.huge, "\n")
end
end
local function save(filename)
doc():save(filename)
core.log("Saved \"%s\"", doc().filename)
end
local commands = {
["doc:undo"] = function()
doc():undo()
end,
["doc:redo"] = function()
doc():redo()
end,
["doc:cut"] = function()
if doc():has_selection() then
local text = doc():get_text(doc():get_selection())
system.set_clipboard(text)
doc():delete_to(0)
end
end,
["doc:copy"] = function()
if doc():has_selection() then
local text = doc():get_text(doc():get_selection())
system.set_clipboard(text)
end
end,
["doc:paste"] = function()
doc():text_input(system.get_clipboard():gsub("\r", ""))
end,
["doc:newline"] = function()
local line, col = doc():get_selection()
local indent = doc().lines[line]:match("^[\t ]*")
if col <= #indent then
indent = indent:sub(#indent + 2 - col)
end
doc():text_input("\n" .. indent)
end,
["doc:newline-below"] = function()
local line = doc():get_selection()
local indent = doc().lines[line]:match("^[\t ]*")
doc():insert(line, math.huge, "\n" .. indent)
doc():set_selection(line + 1, math.huge)
end,
["doc:newline-above"] = function()
local line = doc():get_selection()
local indent = doc().lines[line]:match("^[\t ]*")
doc():insert(line, 1, indent .. "\n")
doc():set_selection(line, math.huge)
end,
["doc:delete"] = function()
local line, col = doc():get_selection()
if not doc():has_selection() and doc().lines[line]:find("^%s*$", col) then
doc():remove(line, col, line, math.huge)
end
doc():delete_to(translate.next_char)
end,
["doc:backspace"] = function()
local line, col = doc():get_selection()
if not doc():has_selection() then
local text = doc():get_text(line, 1, line, col)
if #text >= config.indent_size and text:find("^ *$") then
doc():delete_to(0, -config.indent_size)
return
end
end
doc():delete_to(translate.previous_char)
end,
["doc:select-all"] = function()
doc():set_selection(1, 1, math.huge, math.huge)
end,
["doc:select-none"] = function()
local line, col = doc():get_selection()
doc():set_selection(line, col)
end,
["doc:select-lines"] = function()
local line1, _, line2, _, swap = doc():get_selection(true)
append_line_if_last_line(line2)
doc():set_selection(line1, 1, line2 + 1, 1, swap)
end,
["doc:select-word"] = function()
local line1, col1 = doc():get_selection(true)
local line1, col1 = translate.start_of_word(doc(), line1, col1)
local line2, col2 = translate.end_of_word(doc(), line1, col1)
doc():set_selection(line2, col2, line1, col1)
end,
["doc:join-lines"] = function()
local line1, _, line2 = doc():get_selection(true)
if line1 == line2 then line2 = line2 + 1 end
local text = doc():get_text(line1, 1, line2, math.huge)
text = text:gsub("\n[\t ]*", " ")
doc():insert(line1, 1, text)
doc():remove(line1, #text + 1, line2, math.huge)
if doc():has_selection() then
doc():set_selection(line1, math.huge)
end
end,
["doc:indent"] = function()
local text = get_indent_string()
if doc():has_selection() then
insert_at_start_of_selected_lines(text)
else
doc():text_input(text)
end
end,
["doc:unindent"] = function()
local text = get_indent_string()
remove_from_start_of_selected_lines(text)
end,
["doc:duplicate-lines"] = function()
local line1, col1, line2, col2, swap = doc():get_selection(true)
append_line_if_last_line(line2)
local text = doc():get_text(line1, 1, line2 + 1, 1)
doc():insert(line2 + 1, 1, text)
local n = line2 - line1 + 1
doc():set_selection(line1 + n, col1, line2 + n, col2, swap)
end,
["doc:delete-lines"] = function()
local line1, col1, line2 = doc():get_selection(true)
append_line_if_last_line(line2)
doc():remove(line1, 1, line2 + 1, 1)
doc():set_selection(line1, col1)
end,
["doc:move-lines-up"] = function()
local line1, col1, line2, col2, swap = doc():get_selection(true)
append_line_if_last_line(line2)
if line1 > 1 then
local text = doc().lines[line1 - 1]
doc():insert(line2 + 1, 1, text)
doc():remove(line1 - 1, 1, line1, 1)
doc():set_selection(line1 - 1, col1, line2 - 1, col2, swap)
end
end,
["doc:move-lines-down"] = function()
local line1, col1, line2, col2, swap = doc():get_selection(true)
append_line_if_last_line(line2 + 1)
if line2 < #doc().lines then
local text = doc().lines[line2 + 1]
doc():remove(line2 + 1, 1, line2 + 2, 1)
doc():insert(line1, 1, text)
doc():set_selection(line1 + 1, col1, line2 + 1, col2, swap)
end
end,
["doc:toggle-line-comments"] = function()
local comment = doc().syntax.comment
if not comment then return end
local comment_text = comment .. " "
local line1, _, line2 = doc():get_selection(true)
local uncomment = true
for line = line1, line2 do
local text = doc().lines[line]
if text:find("%S") and text:find(comment_text, 1, true) ~= 1 then
uncomment = false
end
end
if uncomment then
remove_from_start_of_selected_lines(comment_text, true)
else
insert_at_start_of_selected_lines(comment_text, true)
end
end,
["doc:upper-case"] = function()
doc():replace(string.upper)
end,
["doc:lower-case"] = function()
doc():replace(string.lower)
end,
["doc:go-to-line"] = function()
local dv = dv()
local items
local function init_items()
if items then return end
items = {}
local mt = { __tostring = function(x) return x.text end }
for i, line in ipairs(dv.doc.lines) do
local item = { text = line:sub(1, -2), line = i, info = "line: " .. i }
table.insert(items, setmetatable(item, mt))
end
end
core.command_view:enter("Go To Line", function(text, item)
local line = item and item.line or tonumber(text)
if not line then
core.error("Invalid line number or unmatched string")
return
end
dv.doc:set_selection(line, 1 )
dv:scroll_to_line(line, true)
end, function(text)
if not text:find("^%d*$") then
init_items()
return common.fuzzy_match(items, text)
end
end)
end,
["doc:toggle-line-ending"] = function()
doc().crlf = not doc().crlf
end,
["doc:save-as"] = function()
if doc().filename then
core.command_view:set_text(doc().filename)
end
core.command_view:enter("Save As", function(filename)
save(filename)
end, common.path_suggest)
end,
["doc:save"] = function()
if doc().filename then
save()
else
command.perform("doc:save-as")
end
end,
["doc:rename"] = function()
local old_filename = doc().filename
if not old_filename then
core.error("Cannot rename unsaved doc")
return
end
core.command_view:set_text(old_filename)
core.command_view:enter("Rename", function(filename)
doc():save(filename)
core.log("Renamed \"%s\" to \"%s\"", old_filename, filename)
if filename ~= old_filename then
os.remove(old_filename)
end
end, common.path_suggest)
end,
}
local translations = {
["previous-char"] = translate.previous_char,
["next-char"] = translate.next_char,
["previous-word-start"] = translate.previous_word_start,
["next-word-end"] = translate.next_word_end,
["previous-block-start"] = translate.previous_block_start,
["next-block-end"] = translate.next_block_end,
["start-of-doc"] = translate.start_of_doc,
["end-of-doc"] = translate.end_of_doc,
["start-of-line"] = translate.start_of_line,
["end-of-line"] = translate.end_of_line,
["start-of-word"] = translate.start_of_word,
["end-of-word"] = translate.end_of_word,
["previous-line"] = DocView.translate.previous_line,
["next-line"] = DocView.translate.next_line,
["previous-page"] = DocView.translate.previous_page,
["next-page"] = DocView.translate.next_page,
}
for name, fn in pairs(translations) do
commands["doc:move-to-" .. name] = function() doc():move_to(fn, dv()) end
commands["doc:select-to-" .. name] = function() doc():select_to(fn, dv()) end
commands["doc:delete-to-" .. name] = function() doc():delete_to(fn, dv()) end
end
commands["doc:move-to-previous-char"] = function()
if doc():has_selection() then
local line, col = doc():get_selection(true)
doc():set_selection(line, col)
else
doc():move_to(translate.previous_char)
end
end
commands["doc:move-to-next-char"] = function()
if doc():has_selection() then
local _, _, line, col = doc():get_selection(true)
doc():set_selection(line, col)
else
doc():move_to(translate.next_char)
end
end
command.add("core.docview", commands)

View file

@ -0,0 +1,170 @@
local core = require "core"
local command = require "core.command"
local config = require "core.config"
local search = require "core.doc.search"
local DocView = require "core.docview"
local max_previous_finds = 50
local function doc()
return core.active_view.doc
end
local previous_finds
local last_doc
local last_fn, last_text
local function push_previous_find(doc, sel)
if last_doc ~= doc then
last_doc = doc
previous_finds = {}
end
if #previous_finds >= max_previous_finds then
table.remove(previous_finds, 1)
end
table.insert(previous_finds, sel or { doc:get_selection() })
end
local function find(label, search_fn)
local dv = core.active_view
local sel = { dv.doc:get_selection() }
local text = dv.doc:get_text(table.unpack(sel))
local found = false
core.command_view:set_text(text, true)
core.command_view:enter(label, function(text)
if found then
last_fn, last_text = search_fn, text
previous_finds = {}
push_previous_find(dv.doc, sel)
else
core.error("Couldn't find %q", text)
dv.doc:set_selection(table.unpack(sel))
dv:scroll_to_make_visible(sel[1], sel[2])
end
end, function(text)
local ok, line1, col1, line2, col2 = pcall(search_fn, dv.doc, sel[1], sel[2], text)
if ok and line1 and text ~= "" then
dv.doc:set_selection(line2, col2, line1, col1)
dv:scroll_to_line(line2, true)
found = true
else
dv.doc:set_selection(table.unpack(sel))
found = false
end
end, function(explicit)
if explicit then
dv.doc:set_selection(table.unpack(sel))
dv:scroll_to_make_visible(sel[1], sel[2])
end
end)
end
local function replace(kind, default, fn)
core.command_view:set_text(default, true)
core.command_view:enter("Find To Replace " .. kind, function(old)
core.command_view:set_text(old, true)
local s = string.format("Replace %s %q With", kind, old)
core.command_view:enter(s, function(new)
local n = doc():replace(function(text)
return fn(text, old, new)
end)
core.log("Replaced %d instance(s) of %s %q with %q", n, kind, old, new)
end)
end)
end
local function has_selection()
return core.active_view:is(DocView)
and core.active_view.doc:has_selection()
end
command.add(has_selection, {
["find-replace:select-next"] = function()
local l1, c1, l2, c2 = doc():get_selection(true)
local text = doc():get_text(l1, c1, l2, c2)
local l1, c1, l2, c2 = search.find(doc(), l2, c2, text, { wrap = true })
if l2 then doc():set_selection(l2, c2, l1, c1) end
end
})
command.add("core.docview", {
["find-replace:find"] = function()
find("Find Text", function(doc, line, col, text)
local opt = { wrap = true, no_case = true }
return search.find(doc, line, col, text, opt)
end)
end,
["find-replace:find-pattern"] = function()
find("Find Text Pattern", function(doc, line, col, text)
local opt = { wrap = true, no_case = true, pattern = true }
return search.find(doc, line, col, text, opt)
end)
end,
["find-replace:repeat-find"] = function()
if not last_fn then
core.error("No find to continue from")
else
local line, col = doc():get_selection()
local line1, col1, line2, col2 = last_fn(doc(), line, col, last_text)
if line1 then
push_previous_find(doc())
doc():set_selection(line2, col2, line1, col1)
core.active_view:scroll_to_line(line2, true)
end
end
end,
["find-replace:previous-find"] = function()
local sel = table.remove(previous_finds)
if not sel or doc() ~= last_doc then
core.error("No previous finds")
return
end
doc():set_selection(table.unpack(sel))
core.active_view:scroll_to_line(sel[3], true)
end,
["find-replace:replace"] = function()
replace("Text", "", function(text, old, new)
return text:gsub(old:gsub("%W", "%%%1"), new:gsub("%%", "%%%%"), nil)
end)
end,
["find-replace:replace-pattern"] = function()
replace("Pattern", "", function(text, old, new)
return text:gsub(old, new)
end)
end,
["find-replace:replace-symbol"] = function()
local first = ""
if doc():has_selection() then
local text = doc():get_text(doc():get_selection())
first = text:match(config.symbol_pattern) or ""
end
replace("Symbol", first, function(text, old, new)
local n = 0
local res = text:gsub(config.symbol_pattern, function(sym)
if old == sym then
n = n + 1
return new
end
end)
return res, n
end)
end,
})

105
vendor/lite/data/core/commands/root.lua vendored Normal file
View file

@ -0,0 +1,105 @@
local core = require "core"
local style = require "core.style"
local DocView = require "core.docview"
local command = require "core.command"
local common = require "core.common"
local t = {
["root:close"] = function()
local node = core.root_view:get_active_node()
node:close_active_view(core.root_view.root_node)
end,
["root:switch-to-previous-tab"] = function()
local node = core.root_view:get_active_node()
local idx = node:get_view_idx(core.active_view)
idx = idx - 1
if idx < 1 then idx = #node.views end
node:set_active_view(node.views[idx])
end,
["root:switch-to-next-tab"] = function()
local node = core.root_view:get_active_node()
local idx = node:get_view_idx(core.active_view)
idx = idx + 1
if idx > #node.views then idx = 1 end
node:set_active_view(node.views[idx])
end,
["root:move-tab-left"] = function()
local node = core.root_view:get_active_node()
local idx = node:get_view_idx(core.active_view)
if idx > 1 then
table.remove(node.views, idx)
table.insert(node.views, idx - 1, core.active_view)
end
end,
["root:move-tab-right"] = function()
local node = core.root_view:get_active_node()
local idx = node:get_view_idx(core.active_view)
if idx < #node.views then
table.remove(node.views, idx)
table.insert(node.views, idx + 1, core.active_view)
end
end,
["root:shrink"] = function()
local node = core.root_view:get_active_node()
local parent = node:get_parent_node(core.root_view.root_node)
local n = (parent.a == node) and -0.1 or 0.1
parent.divider = common.clamp(parent.divider + n, 0.1, 0.9)
end,
["root:grow"] = function()
local node = core.root_view:get_active_node()
local parent = node:get_parent_node(core.root_view.root_node)
local n = (parent.a == node) and 0.1 or -0.1
parent.divider = common.clamp(parent.divider + n, 0.1, 0.9)
end,
}
for i = 1, 9 do
t["root:switch-to-tab-" .. i] = function()
local node = core.root_view:get_active_node()
local view = node.views[i]
if view then
node:set_active_view(view)
end
end
end
for _, dir in ipairs { "left", "right", "up", "down" } do
t["root:split-" .. dir] = function()
local node = core.root_view:get_active_node()
local av = node.active_view
node:split(dir)
if av:is(DocView) then
core.root_view:open_doc(av.doc)
end
end
t["root:switch-to-" .. dir] = function()
local node = core.root_view:get_active_node()
local x, y
if dir == "left" or dir == "right" then
y = node.position.y + node.size.y / 2
x = node.position.x + (dir == "left" and -1 or node.size.x + style.divider_size)
else
x = node.position.x + node.size.x / 2
y = node.position.y + (dir == "up" and -1 or node.size.y + style.divider_size)
end
local node = core.root_view.root_node:get_child_overlapping_point(x, y)
if not node:get_locked_size() then
core.set_active_view(node.active_view)
end
end
end
command.add(function()
local node = core.root_view:get_active_node()
return not node:get_locked_size()
end, t)

256
vendor/lite/data/core/commandview.lua vendored Normal file
View file

@ -0,0 +1,256 @@
local core = require "core"
local common = require "core.common"
local style = require "core.style"
local Doc = require "core.doc"
local DocView = require "core.docview"
local View = require "core.view"
local SingleLineDoc = Doc:extend()
function SingleLineDoc:insert(line, col, text)
SingleLineDoc.super.insert(self, line, col, text:gsub("\n", ""))
end
local CommandView = DocView:extend()
local max_suggestions = 10
local noop = function() end
local default_state = {
submit = noop,
suggest = noop,
cancel = noop,
}
function CommandView:new()
CommandView.super.new(self, SingleLineDoc())
self.suggestion_idx = 1
self.suggestions = {}
self.suggestions_height = 0
self.last_change_id = 0
self.gutter_width = 0
self.gutter_text_brightness = 0
self.selection_offset = 0
self.state = default_state
self.font = "font"
self.size.y = 0
self.label = ""
end
function CommandView:get_name()
return View.get_name(self)
end
function CommandView:get_line_screen_position()
local x = CommandView.super.get_line_screen_position(self, 1)
local _, y = self:get_content_offset()
local lh = self:get_line_height()
return x, y + (self.size.y - lh) / 2
end
function CommandView:get_scrollable_size()
return 0
end
function CommandView:scroll_to_make_visible()
-- no-op function to disable this functionality
end
function CommandView:get_text()
return self.doc:get_text(1, 1, 1, math.huge)
end
function CommandView:set_text(text, select)
self.doc:remove(1, 1, math.huge, math.huge)
self.doc:text_input(text)
if select then
self.doc:set_selection(math.huge, math.huge, 1, 1)
end
end
function CommandView:move_suggestion_idx(dir)
local n = self.suggestion_idx + dir
self.suggestion_idx = common.clamp(n, 1, #self.suggestions)
self:complete()
self.last_change_id = self.doc:get_change_id()
end
function CommandView:complete()
if #self.suggestions > 0 then
self:set_text(self.suggestions[self.suggestion_idx].text)
end
end
function CommandView:submit()
local suggestion = self.suggestions[self.suggestion_idx]
local text = self:get_text()
local submit = self.state.submit
self:exit(true)
submit(text, suggestion)
end
function CommandView:enter(text, submit, suggest, cancel)
if self.state ~= default_state then
return
end
self.state = {
submit = submit or noop,
suggest = suggest or noop,
cancel = cancel or noop,
}
core.set_active_view(self)
self:update_suggestions()
self.gutter_text_brightness = 100
self.label = text .. ": "
end
function CommandView:exit(submitted, inexplicit)
if core.active_view == self then
core.set_active_view(core.last_active_view)
end
local cancel = self.state.cancel
self.state = default_state
self.doc:reset()
self.suggestions = {}
if not submitted then cancel(not inexplicit) end
end
function CommandView:get_gutter_width()
return self.gutter_width
end
function CommandView:get_suggestion_line_height()
return self:get_font():get_height() + style.padding.y
end
function CommandView:update_suggestions()
local t = self.state.suggest(self:get_text()) or {}
local res = {}
for i, item in ipairs(t) do
if i == max_suggestions then
break
end
if type(item) == "string" then
item = { text = item }
end
res[i] = item
end
self.suggestions = res
self.suggestion_idx = 1
end
function CommandView:update()
CommandView.super.update(self)
if core.active_view ~= self and self.state ~= default_state then
self:exit(false, true)
end
-- update suggestions if text has changed
if self.last_change_id ~= self.doc:get_change_id() then
self:update_suggestions()
self.last_change_id = self.doc:get_change_id()
end
-- update gutter text color brightness
self:move_towards("gutter_text_brightness", 0, 0.1)
-- update gutter width
local dest = self:get_font():get_width(self.label) + style.padding.x
if self.size.y <= 0 then
self.gutter_width = dest
else
self:move_towards("gutter_width", dest)
end
-- update suggestions box height
local lh = self:get_suggestion_line_height()
local dest = #self.suggestions * lh
self:move_towards("suggestions_height", dest)
-- update suggestion cursor offset
local dest = self.suggestion_idx * self:get_suggestion_line_height()
self:move_towards("selection_offset", dest)
-- update size based on whether this is the active_view
local dest = 0
if self == core.active_view then
dest = style.font:get_height() + style.padding.y * 2
end
self:move_towards(self.size, "y", dest)
end
function CommandView:draw_line_highlight()
-- no-op function to disable this functionality
end
function CommandView:draw_line_gutter(idx, x, y)
local yoffset = self:get_line_text_y_offset()
local pos = self.position
local color = common.lerp(style.text, style.accent, self.gutter_text_brightness / 100)
core.push_clip_rect(pos.x, pos.y, self:get_gutter_width(), self.size.y)
x = x + style.padding.x
renderer.draw_text(self:get_font(), self.label, x, y + yoffset, color)
core.pop_clip_rect()
end
local function draw_suggestions_box(self)
local lh = self:get_suggestion_line_height()
local dh = style.divider_size
local x, _ = self:get_line_screen_position()
local h = math.ceil(self.suggestions_height)
local rx, ry, rw, rh = self.position.x, self.position.y - h - dh, self.size.x, h
-- draw suggestions background
if #self.suggestions > 0 then
renderer.draw_rect(rx, ry, rw, rh, style.background3)
renderer.draw_rect(rx, ry - dh, rw, dh, style.divider)
local y = self.position.y - self.selection_offset - dh
renderer.draw_rect(rx, y, rw, lh, style.line_highlight)
end
-- draw suggestion text
core.push_clip_rect(rx, ry, rw, rh)
for i, item in ipairs(self.suggestions) do
local color = (i == self.suggestion_idx) and style.accent or style.text
local y = self.position.y - i * lh - dh
common.draw_text(self:get_font(), color, item.text, nil, x, y, 0, lh)
if item.info then
local w = self.size.x - x - style.padding.x
common.draw_text(self:get_font(), style.dim, item.info, "right", x, y, w, lh)
end
end
core.pop_clip_rect()
end
function CommandView:draw()
CommandView.super.draw(self)
core.root_view:defer_draw(draw_suggestions_box, self)
end
return CommandView

140
vendor/lite/data/core/common.lua vendored Normal file
View file

@ -0,0 +1,140 @@
local common = {}
function common.is_utf8_cont(char)
local byte = char:byte()
return byte >= 0x80 and byte < 0xc0
end
function common.utf8_chars(text)
return text:gmatch("[%z\001-\127\194-\244][\128-\191]*")
end
function common.clamp(n, lo, hi)
return math.max(math.min(n, hi), lo)
end
function common.round(n)
return n >= 0 and math.floor(n + 0.5) or math.ceil(n - 0.5)
end
function common.lerp(a, b, t)
if type(a) ~= "table" then
return a + (b - a) * t
end
local res = {}
for k, v in pairs(b) do
res[k] = common.lerp(a[k], v, t)
end
return res
end
function common.color(str)
local r, g, b, a = str:match("#(%x%x)(%x%x)(%x%x)")
if r then
r = tonumber(r, 16)
g = tonumber(g, 16)
b = tonumber(b, 16)
a = 1
elseif str:match("rgba?%s*%([%d%s%.,]+%)") then
local f = str:gmatch("[%d.]+")
r = (f() or 0)
g = (f() or 0)
b = (f() or 0)
a = f() or 1
else
error(string.format("bad color string '%s'", str))
end
return r, g, b, a * 0xff
end
local function compare_score(a, b)
return a.score > b.score
end
local function fuzzy_match_items(items, needle)
local res = {}
for _, item in ipairs(items) do
local score = system.fuzzy_match(tostring(item), needle)
if score then
table.insert(res, { text = item, score = score })
end
end
table.sort(res, compare_score)
for i, item in ipairs(res) do
res[i] = item.text
end
return res
end
function common.fuzzy_match(haystack, needle)
if type(haystack) == "table" then
return fuzzy_match_items(haystack, needle)
end
return system.fuzzy_match(haystack, needle)
end
function common.path_suggest(text)
local path, name = text:match("^(.-)([^/\\]*)$")
local files = system.list_dir(path == "" and "." or path) or {}
local res = {}
for _, file in ipairs(files) do
file = path .. file
local info = system.get_file_info(file)
if info then
if info.type == "dir" then
file = file .. PATHSEP
end
if file:lower():find(text:lower(), nil, true) == 1 then
table.insert(res, file)
end
end
end
return res
end
function common.match_pattern(text, pattern, ...)
if type(pattern) == "string" then
return text:find(pattern, ...)
end
for _, p in ipairs(pattern) do
local s, e = common.match_pattern(text, p, ...)
if s then return s, e end
end
return false
end
function common.draw_text(font, color, text, align, x,y,w,h)
local tw, th = font:get_width(text), font:get_height(text)
if align == "center" then
x = x + (w - tw) / 2
elseif align == "right" then
x = x + (w - tw)
end
y = common.round(y + (h - th) / 2)
return renderer.draw_text(font, text, x, y, color), y + th
end
function common.bench(name, fn, ...)
local start = system.get_time()
local res = fn(...)
local t = system.get_time() - start
local ms = t * 1000
local per = (t / (1 / 60)) * 100
print(string.format("*** %-16s : %8.3fms %6.2f%%", name, ms, per))
return res
end
return common

20
vendor/lite/data/core/config.lua vendored Normal file
View file

@ -0,0 +1,20 @@
local config = {}
config.project_scan_rate = 5
config.fps = 60
config.max_log_items = 80
config.message_timeout = 3
config.mouse_wheel_scroll = 50 * SCALE
config.file_size_limit = 10
config.ignore_files = "^%."
config.symbol_pattern = "[%a_][%w_]*"
config.non_word_chars = " \t\n/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-"
config.undo_merge_timeout = 0.3
config.max_undos = 10000
config.highlight_current_line = true
config.line_height = 1.2
config.indent_size = 2
config.tab_type = "soft"
config.line_limit = 80
return config

View file

@ -0,0 +1,80 @@
local core = require "core"
local config = require "core.config"
local tokenizer = require "core.tokenizer"
local Object = require "core.object"
local Highlighter = Object:extend()
function Highlighter:new(doc)
self.doc = doc
self:reset()
-- init incremental syntax highlighting
core.add_thread(function()
while true do
if self.first_invalid_line > self.max_wanted_line then
self.max_wanted_line = 0
coroutine.yield(1 / config.fps)
else
local max = math.min(self.first_invalid_line + 40, self.max_wanted_line)
for i = self.first_invalid_line, max do
local state = (i > 1) and self.lines[i - 1].state
local line = self.lines[i]
if not (line and line.init_state == state) then
self.lines[i] = self:tokenize_line(i, state)
end
end
self.first_invalid_line = max + 1
core.redraw = true
coroutine.yield()
end
end
end, self)
end
function Highlighter:reset()
self.lines = {}
self.first_invalid_line = 1
self.max_wanted_line = 0
end
function Highlighter:invalidate(idx)
self.first_invalid_line = math.min(self.first_invalid_line, idx)
self.max_wanted_line = math.min(self.max_wanted_line, #self.doc.lines)
end
function Highlighter:tokenize_line(idx, state)
local res = {}
res.init_state = state
res.text = self.doc.lines[idx]
res.tokens, res.state = tokenizer.tokenize(self.doc.syntax, res.text, state)
return res
end
function Highlighter:get_line(idx)
local line = self.lines[idx]
if not line or line.text ~= self.doc.lines[idx] then
local prev = self.lines[idx - 1]
line = self:tokenize_line(idx, prev and prev.state)
self.lines[idx] = line
end
self.max_wanted_line = math.max(self.max_wanted_line, idx)
return line
end
function Highlighter:each_token(idx)
return tokenizer.each_token(self:get_line(idx).tokens)
end
return Highlighter

393
vendor/lite/data/core/doc/init.lua vendored Normal file
View file

@ -0,0 +1,393 @@
local Object = require "core.object"
local Highlighter = require "core.doc.highlighter"
local syntax = require "core.syntax"
local config = require "core.config"
local common = require "core.common"
local Doc = Object:extend()
local function split_lines(text)
local res = {}
for line in (text .. "\n"):gmatch("(.-)\n") do
table.insert(res, line)
end
return res
end
local function splice(t, at, remove, insert)
insert = insert or {}
local offset = #insert - remove
local old_len = #t
if offset < 0 then
for i = at - offset, old_len - offset do
t[i + offset] = t[i]
end
elseif offset > 0 then
for i = old_len, at, -1 do
t[i + offset] = t[i]
end
end
for i, item in ipairs(insert) do
t[at + i - 1] = item
end
end
function Doc:new(filename)
self:reset()
if filename then
self:load(filename)
end
end
function Doc:reset()
self.lines = { "\n" }
self.selection = { a = { line=1, col=1 }, b = { line=1, col=1 } }
self.undo_stack = { idx = 1 }
self.redo_stack = { idx = 1 }
self.clean_change_id = 1
self.highlighter = Highlighter(self)
self:reset_syntax()
end
function Doc:reset_syntax()
local header = self:get_text(1, 1, self:position_offset(1, 1, 128))
local syn = syntax.get(self.filename or "", header)
if self.syntax ~= syn then
self.syntax = syn
self.highlighter:reset()
end
end
function Doc:load(filename)
local fp = assert( io.open(filename, "rb") )
self:reset()
self.filename = filename
self.lines = {}
for line in fp:lines() do
if line:byte(-1) == 13 then
line = line:sub(1, -2)
self.crlf = true
end
table.insert(self.lines, line .. "\n")
end
if #self.lines == 0 then
table.insert(self.lines, "\n")
end
fp:close()
self:reset_syntax()
end
function Doc:save(filename)
filename = filename or assert(self.filename, "no filename set to default to")
local fp = assert( io.open(filename, "wb") )
for _, line in ipairs(self.lines) do
if self.crlf then line = line:gsub("\n", "\r\n") end
fp:write(line)
end
fp:close()
self.filename = filename or self.filename
self:reset_syntax()
self:clean()
end
function Doc:get_name()
return self.filename or "unsaved"
end
function Doc:is_dirty()
return self.clean_change_id ~= self:get_change_id()
end
function Doc:clean()
self.clean_change_id = self:get_change_id()
end
function Doc:get_change_id()
return self.undo_stack.idx
end
function Doc:set_selection(line1, col1, line2, col2, swap)
assert(not line2 == not col2, "expected 2 or 4 arguments")
if swap then line1, col1, line2, col2 = line2, col2, line1, col1 end
line1, col1 = self:sanitize_position(line1, col1)
line2, col2 = self:sanitize_position(line2 or line1, col2 or col1)
self.selection.a.line, self.selection.a.col = line1, col1
self.selection.b.line, self.selection.b.col = line2, col2
end
local function sort_positions(line1, col1, line2, col2)
if line1 > line2
or line1 == line2 and col1 > col2 then
return line2, col2, line1, col1, true
end
return line1, col1, line2, col2, false
end
function Doc:get_selection(sort)
local a, b = self.selection.a, self.selection.b
if sort then
return sort_positions(a.line, a.col, b.line, b.col)
end
return a.line, a.col, b.line, b.col
end
function Doc:has_selection()
local a, b = self.selection.a, self.selection.b
return not (a.line == b.line and a.col == b.col)
end
function Doc:sanitize_selection()
self:set_selection(self:get_selection())
end
function Doc:sanitize_position(line, col)
line = common.clamp(line, 1, #self.lines)
col = common.clamp(col, 1, #self.lines[line])
return line, col
end
local function position_offset_func(self, line, col, fn, ...)
line, col = self:sanitize_position(line, col)
return fn(self, line, col, ...)
end
local function position_offset_byte(self, line, col, offset)
line, col = self:sanitize_position(line, col)
col = col + offset
while line > 1 and col < 1 do
line = line - 1
col = col + #self.lines[line]
end
while line < #self.lines and col > #self.lines[line] do
col = col - #self.lines[line]
line = line + 1
end
return self:sanitize_position(line, col)
end
local function position_offset_linecol(self, line, col, lineoffset, coloffset)
return self:sanitize_position(line + lineoffset, col + coloffset)
end
function Doc:position_offset(line, col, ...)
if type(...) ~= "number" then
return position_offset_func(self, line, col, ...)
elseif select("#", ...) == 1 then
return position_offset_byte(self, line, col, ...)
elseif select("#", ...) == 2 then
return position_offset_linecol(self, line, col, ...)
else
error("bad number of arguments")
end
end
function Doc:get_text(line1, col1, line2, col2)
line1, col1 = self:sanitize_position(line1, col1)
line2, col2 = self:sanitize_position(line2, col2)
line1, col1, line2, col2 = sort_positions(line1, col1, line2, col2)
if line1 == line2 then
return self.lines[line1]:sub(col1, col2 - 1)
end
local lines = { self.lines[line1]:sub(col1) }
for i = line1 + 1, line2 - 1 do
table.insert(lines, self.lines[i])
end
table.insert(lines, self.lines[line2]:sub(1, col2 - 1))
return table.concat(lines)
end
function Doc:get_char(line, col)
line, col = self:sanitize_position(line, col)
return self.lines[line]:sub(col, col)
end
local function push_undo(undo_stack, time, type, ...)
undo_stack[undo_stack.idx] = { type = type, time = time, ... }
undo_stack[undo_stack.idx - config.max_undos] = nil
undo_stack.idx = undo_stack.idx + 1
end
local function pop_undo(self, undo_stack, redo_stack)
-- pop command
local cmd = undo_stack[undo_stack.idx - 1]
if not cmd then return end
undo_stack.idx = undo_stack.idx - 1
-- handle command
if cmd.type == "insert" then
local line, col, text = table.unpack(cmd)
self:raw_insert(line, col, text, redo_stack, cmd.time)
elseif cmd.type == "remove" then
local line1, col1, line2, col2 = table.unpack(cmd)
self:raw_remove(line1, col1, line2, col2, redo_stack, cmd.time)
elseif cmd.type == "selection" then
self.selection.a.line, self.selection.a.col = cmd[1], cmd[2]
self.selection.b.line, self.selection.b.col = cmd[3], cmd[4]
end
-- if next undo command is within the merge timeout then treat as a single
-- command and continue to execute it
local next = undo_stack[undo_stack.idx - 1]
if next and math.abs(cmd.time - next.time) < config.undo_merge_timeout then
return pop_undo(self, undo_stack, redo_stack)
end
end
function Doc:raw_insert(line, col, text, undo_stack, time)
-- split text into lines and merge with line at insertion point
local lines = split_lines(text)
local before = self.lines[line]:sub(1, col - 1)
local after = self.lines[line]:sub(col)
for i = 1, #lines - 1 do
lines[i] = lines[i] .. "\n"
end
lines[1] = before .. lines[1]
lines[#lines] = lines[#lines] .. after
-- splice lines into line array
splice(self.lines, line, 1, lines)
-- push undo
local line2, col2 = self:position_offset(line, col, #text)
push_undo(undo_stack, time, "selection", self:get_selection())
push_undo(undo_stack, time, "remove", line, col, line2, col2)
-- update highlighter and assure selection is in bounds
self.highlighter:invalidate(line)
self:sanitize_selection()
end
function Doc:raw_remove(line1, col1, line2, col2, undo_stack, time)
-- push undo
local text = self:get_text(line1, col1, line2, col2)
push_undo(undo_stack, time, "selection", self:get_selection())
push_undo(undo_stack, time, "insert", line1, col1, text)
-- get line content before/after removed text
local before = self.lines[line1]:sub(1, col1 - 1)
local after = self.lines[line2]:sub(col2)
-- splice line into line array
splice(self.lines, line1, line2 - line1 + 1, { before .. after })
-- update highlighter and assure selection is in bounds
self.highlighter:invalidate(line1)
self:sanitize_selection()
end
function Doc:insert(line, col, text)
self.redo_stack = { idx = 1 }
line, col = self:sanitize_position(line, col)
self:raw_insert(line, col, text, self.undo_stack, system.get_time())
end
function Doc:remove(line1, col1, line2, col2)
self.redo_stack = { idx = 1 }
line1, col1 = self:sanitize_position(line1, col1)
line2, col2 = self:sanitize_position(line2, col2)
line1, col1, line2, col2 = sort_positions(line1, col1, line2, col2)
self:raw_remove(line1, col1, line2, col2, self.undo_stack, system.get_time())
end
function Doc:undo()
pop_undo(self, self.undo_stack, self.redo_stack)
end
function Doc:redo()
pop_undo(self, self.redo_stack, self.undo_stack)
end
function Doc:text_input(text)
if self:has_selection() then
self:delete_to()
end
local line, col = self:get_selection()
self:insert(line, col, text)
self:move_to(#text)
end
function Doc:replace(fn)
local line1, col1, line2, col2, swap
local had_selection = self:has_selection()
if had_selection then
line1, col1, line2, col2, swap = self:get_selection(true)
else
line1, col1, line2, col2 = 1, 1, #self.lines, #self.lines[#self.lines]
end
local old_text = self:get_text(line1, col1, line2, col2)
local new_text, n = fn(old_text)
if old_text ~= new_text then
self:insert(line2, col2, new_text)
self:remove(line1, col1, line2, col2)
if had_selection then
line2, col2 = self:position_offset(line1, col1, #new_text)
self:set_selection(line1, col1, line2, col2, swap)
end
end
return n
end
function Doc:delete_to(...)
local line, col = self:get_selection(true)
if self:has_selection() then
self:remove(self:get_selection())
else
local line2, col2 = self:position_offset(line, col, ...)
self:remove(line, col, line2, col2)
line, col = sort_positions(line, col, line2, col2)
end
self:set_selection(line, col)
end
function Doc:move_to(...)
local line, col = self:get_selection()
self:set_selection(self:position_offset(line, col, ...))
end
function Doc:select_to(...)
local line, col, line2, col2 = self:get_selection()
line, col = self:position_offset(line, col, ...)
self:set_selection(line, col, line2, col2)
end
return Doc

52
vendor/lite/data/core/doc/search.lua vendored Normal file
View file

@ -0,0 +1,52 @@
local search = {}
local default_opt = {}
local function pattern_lower(str)
if str:sub(1, 1) == "%" then
return str
end
return str:lower()
end
local function init_args(doc, line, col, text, opt)
opt = opt or default_opt
line, col = doc:sanitize_position(line, col)
if opt.no_case then
if opt.pattern then
text = text:gsub("%%?.", pattern_lower)
else
text = text:lower()
end
end
return doc, line, col, text, opt
end
function search.find(doc, line, col, text, opt)
doc, line, col, text, opt = init_args(doc, line, col, text, opt)
for line = line, #doc.lines do
local line_text = doc.lines[line]
if opt.no_case then
line_text = line_text:lower()
end
local s, e = line_text:find(text, col, not opt.pattern)
if s then
return line, s, line, e + 1
end
col = 1
end
if opt.wrap then
opt = { no_case = opt.no_case, pattern = opt.pattern }
return search.find(doc, 1, 1, text, opt)
end
end
return search

136
vendor/lite/data/core/doc/translate.lua vendored Normal file
View file

@ -0,0 +1,136 @@
local common = require "core.common"
local config = require "core.config"
-- functions for translating a Doc position to another position these functions
-- can be passed to Doc:move_to|select_to|delete_to()
local translate = {}
local function is_non_word(char)
return config.non_word_chars:find(char, nil, true)
end
function translate.previous_char(doc, line, col)
repeat
line, col = doc:position_offset(line, col, -1)
until not common.is_utf8_cont(doc:get_char(line, col))
return line, col
end
function translate.next_char(doc, line, col)
repeat
line, col = doc:position_offset(line, col, 1)
until not common.is_utf8_cont(doc:get_char(line, col))
return line, col
end
function translate.previous_word_start(doc, line, col)
local prev
while line > 1 or col > 1 do
local l, c = doc:position_offset(line, col, -1)
local char = doc:get_char(l, c)
if prev and prev ~= char or not is_non_word(char) then
break
end
prev, line, col = char, l, c
end
return translate.start_of_word(doc, line, col)
end
function translate.next_word_end(doc, line, col)
local prev
local end_line, end_col = translate.end_of_doc(doc, line, col)
while line < end_line or col < end_col do
local char = doc:get_char(line, col)
if prev and prev ~= char or not is_non_word(char) then
break
end
line, col = doc:position_offset(line, col, 1)
prev = char
end
return translate.end_of_word(doc, line, col)
end
function translate.start_of_word(doc, line, col)
while true do
local line2, col2 = doc:position_offset(line, col, -1)
local char = doc:get_char(line2, col2)
if is_non_word(char)
or line == line2 and col == col2 then
break
end
line, col = line2, col2
end
return line, col
end
function translate.end_of_word(doc, line, col)
while true do
local line2, col2 = doc:position_offset(line, col, 1)
local char = doc:get_char(line, col)
if is_non_word(char)
or line == line2 and col == col2 then
break
end
line, col = line2, col2
end
return line, col
end
function translate.previous_block_start(doc, line, col)
while true do
line = line - 1
if line <= 1 then
return 1, 1
end
if doc.lines[line-1]:find("^%s*$")
and not doc.lines[line]:find("^%s*$") then
return line, (doc.lines[line]:find("%S"))
end
end
end
function translate.next_block_end(doc, line, col)
while true do
if line >= #doc.lines then
return #doc.lines, 1
end
if doc.lines[line+1]:find("^%s*$")
and not doc.lines[line]:find("^%s*$") then
return line+1, #doc.lines[line+1]
end
line = line + 1
end
end
function translate.start_of_line(doc, line, col)
return line, 1
end
function translate.end_of_line(doc, line, col)
return line, math.huge
end
function translate.start_of_doc(doc, line, col)
return 1, 1
end
function translate.end_of_doc(doc, line, col)
return #doc.lines, #doc.lines[#doc.lines]
end
return translate

383
vendor/lite/data/core/docview.lua vendored Normal file
View file

@ -0,0 +1,383 @@
local core = require "core"
local common = require "core.common"
local config = require "core.config"
local style = require "core.style"
local keymap = require "core.keymap"
local translate = require "core.doc.translate"
local View = require "core.view"
local DocView = View:extend()
local function move_to_line_offset(dv, line, col, offset)
local xo = dv.last_x_offset
if xo.line ~= line or xo.col ~= col then
xo.offset = dv:get_col_x_offset(line, col)
end
xo.line = line + offset
xo.col = dv:get_x_offset_col(line + offset, xo.offset)
return xo.line, xo.col
end
DocView.translate = {
["previous_page"] = function(doc, line, col, dv)
local min, max = dv:get_visible_line_range()
return line - (max - min), 1
end,
["next_page"] = function(doc, line, col, dv)
local min, max = dv:get_visible_line_range()
return line + (max - min), 1
end,
["previous_line"] = function(doc, line, col, dv)
if line == 1 then
return 1, 1
end
return move_to_line_offset(dv, line, col, -1)
end,
["next_line"] = function(doc, line, col, dv)
if line == #doc.lines then
return #doc.lines, math.huge
end
return move_to_line_offset(dv, line, col, 1)
end,
}
local blink_period = 0.8
function DocView:new(doc)
DocView.super.new(self)
self.cursor = "ibeam"
self.scrollable = true
self.doc = assert(doc)
self.font = "code_font"
self.last_x_offset = {}
self.blink_timer = 0
end
function DocView:try_close(do_close)
if self.doc:is_dirty()
and #core.get_views_referencing_doc(self.doc) == 1 then
core.command_view:enter("Unsaved Changes; Confirm Close", function(_, item)
if item.text:match("^[cC]") then
do_close()
elseif item.text:match("^[sS]") then
self.doc:save()
do_close()
end
end, function(text)
local items = {}
if not text:find("^[^cC]") then table.insert(items, "Close Without Saving") end
if not text:find("^[^sS]") then table.insert(items, "Save And Close") end
return items
end)
else
do_close()
end
end
function DocView:get_name()
local post = self.doc:is_dirty() and "*" or ""
local name = self.doc:get_name()
return name:match("[^/%\\]*$") .. post
end
function DocView:get_scrollable_size()
return self:get_line_height() * (#self.doc.lines - 1) + self.size.y
end
function DocView:get_font()
return style[self.font]
end
function DocView:get_line_height()
return math.floor(self:get_font():get_height() * config.line_height)
end
function DocView:get_gutter_width()
return self:get_font():get_width(#self.doc.lines) + style.padding.x * 2
end
function DocView:get_line_screen_position(idx)
local x, y = self:get_content_offset()
local lh = self:get_line_height()
local gw = self:get_gutter_width()
return x + gw, y + (idx-1) * lh + style.padding.y
end
function DocView:get_line_text_y_offset()
local lh = self:get_line_height()
local th = self:get_font():get_height()
return (lh - th) / 2
end
function DocView:get_visible_line_range()
local x, y, x2, y2 = self:get_content_bounds()
local lh = self:get_line_height()
local minline = math.max(1, math.floor(y / lh))
local maxline = math.min(#self.doc.lines, math.floor(y2 / lh) + 1)
return minline, maxline
end
function DocView:get_col_x_offset(line, col)
local text = self.doc.lines[line]
if not text then return 0 end
return self:get_font():get_width(text:sub(1, col - 1))
end
function DocView:get_x_offset_col(line, x)
local text = self.doc.lines[line]
local xoffset, last_i, i = 0, 1, 1
for char in common.utf8_chars(text) do
local w = self:get_font():get_width(char)
if xoffset >= x then
return (xoffset - x > w / 2) and last_i or i
end
xoffset = xoffset + w
last_i = i
i = i + #char
end
return #text
end
function DocView:resolve_screen_position(x, y)
local ox, oy = self:get_line_screen_position(1)
local line = math.floor((y - oy) / self:get_line_height()) + 1
line = common.clamp(line, 1, #self.doc.lines)
local col = self:get_x_offset_col(line, x - ox)
return line, col
end
function DocView:scroll_to_line(line, ignore_if_visible, instant)
local min, max = self:get_visible_line_range()
if not (ignore_if_visible and line > min and line < max) then
local lh = self:get_line_height()
self.scroll.to.y = math.max(0, lh * (line - 1) - self.size.y / 2)
if instant then
self.scroll.y = self.scroll.to.y
end
end
end
function DocView:scroll_to_make_visible(line, col)
local min = self:get_line_height() * (line - 1)
local max = self:get_line_height() * (line + 2) - self.size.y
self.scroll.to.y = math.min(self.scroll.to.y, min)
self.scroll.to.y = math.max(self.scroll.to.y, max)
local gw = self:get_gutter_width()
local xoffset = self:get_col_x_offset(line, col)
local max = xoffset - self.size.x + gw + self.size.x / 5
self.scroll.to.x = math.max(0, max)
end
local function mouse_selection(doc, clicks, line1, col1, line2, col2)
local swap = line2 < line1 or line2 == line1 and col2 <= col1
if swap then
line1, col1, line2, col2 = line2, col2, line1, col1
end
if clicks == 2 then
line1, col1 = translate.start_of_word(doc, line1, col1)
line2, col2 = translate.end_of_word(doc, line2, col2)
elseif clicks == 3 then
if line2 == #doc.lines and doc.lines[#doc.lines] ~= "\n" then
doc:insert(math.huge, math.huge, "\n")
end
line1, col1, line2, col2 = line1, 1, line2 + 1, 1
end
if swap then
return line2, col2, line1, col1
end
return line1, col1, line2, col2
end
function DocView:on_mouse_pressed(button, x, y, clicks)
local caught = DocView.super.on_mouse_pressed(self, button, x, y, clicks)
if caught then
return
end
if keymap.modkeys["shift"] then
if clicks == 1 then
local line1, col1 = select(3, self.doc:get_selection())
local line2, col2 = self:resolve_screen_position(x, y)
self.doc:set_selection(line2, col2, line1, col1)
end
else
local line, col = self:resolve_screen_position(x, y)
self.doc:set_selection(mouse_selection(self.doc, clicks, line, col, line, col))
self.mouse_selecting = { line, col, clicks = clicks }
end
self.blink_timer = 0
end
function DocView:on_mouse_moved(x, y, ...)
DocView.super.on_mouse_moved(self, x, y, ...)
if self:scrollbar_overlaps_point(x, y) or self.dragging_scrollbar then
self.cursor = "arrow"
else
self.cursor = "ibeam"
end
if self.mouse_selecting then
local l1, c1 = self:resolve_screen_position(x, y)
local l2, c2 = table.unpack(self.mouse_selecting)
local clicks = self.mouse_selecting.clicks
self.doc:set_selection(mouse_selection(self.doc, clicks, l1, c1, l2, c2))
end
end
function DocView:on_mouse_released(button)
DocView.super.on_mouse_released(self, button)
self.mouse_selecting = nil
end
function DocView:on_text_input(text)
self.doc:text_input(text)
end
function DocView:update()
-- scroll to make caret visible and reset blink timer if it moved
local line, col = self.doc:get_selection()
if (line ~= self.last_line or col ~= self.last_col) and self.size.x > 0 then
if core.active_view == self then
self:scroll_to_make_visible(line, col)
end
self.blink_timer = 0
self.last_line, self.last_col = line, col
end
-- update blink timer
if self == core.active_view and not self.mouse_selecting then
local n = blink_period / 2
local prev = self.blink_timer
self.blink_timer = (self.blink_timer + 1 / config.fps) % blink_period
if (self.blink_timer > n) ~= (prev > n) then
core.redraw = true
end
end
DocView.super.update(self)
end
function DocView:draw_line_highlight(x, y)
local lh = self:get_line_height()
renderer.draw_rect(x, y, self.size.x, lh, style.line_highlight)
end
function DocView:draw_line_text(idx, x, y)
local tx, ty = x, y + self:get_line_text_y_offset()
local font = self:get_font()
for _, type, text in self.doc.highlighter:each_token(idx) do
local color = style.syntax[type]
tx = renderer.draw_text(font, text, tx, ty, color)
end
end
function DocView:draw_line_body(idx, x, y)
local line, col = self.doc:get_selection()
-- draw selection if it overlaps this line
local line1, col1, line2, col2 = self.doc:get_selection(true)
if idx >= line1 and idx <= line2 then
local text = self.doc.lines[idx]
if line1 ~= idx then col1 = 1 end
if line2 ~= idx then col2 = #text + 1 end
local x1 = x + self:get_col_x_offset(idx, col1)
local x2 = x + self:get_col_x_offset(idx, col2)
local lh = self:get_line_height()
renderer.draw_rect(x1, y, x2 - x1, lh, style.selection)
end
-- draw line highlight if caret is on this line
if config.highlight_current_line and not self.doc:has_selection()
and line == idx and core.active_view == self then
self:draw_line_highlight(x + self.scroll.x, y)
end
-- draw line's text
self:draw_line_text(idx, x, y)
-- draw caret if it overlaps this line
if line == idx and core.active_view == self
and self.blink_timer < blink_period / 2
and system.window_has_focus() then
local lh = self:get_line_height()
local x1 = x + self:get_col_x_offset(line, col)
renderer.draw_rect(x1, y, style.caret_width, lh, style.caret)
end
end
function DocView:draw_line_gutter(idx, x, y)
local color = style.line_number
local line1, _, line2, _ = self.doc:get_selection(true)
if idx >= line1 and idx <= line2 then
color = style.line_number2
end
local yoffset = self:get_line_text_y_offset()
x = x + style.padding.x
renderer.draw_text(self:get_font(), idx, x, y + yoffset, color)
end
function DocView:draw()
self:draw_background(style.background)
local font = self:get_font()
font:set_tab_width(font:get_width(" ") * config.indent_size)
local minline, maxline = self:get_visible_line_range()
local lh = self:get_line_height()
local _, y = self:get_line_screen_position(minline)
local x = self.position.x
for i = minline, maxline do
self:draw_line_gutter(i, x, y)
y = y + lh
end
local x, y = self:get_line_screen_position(minline)
local gw = self:get_gutter_width()
local pos = self.position
core.push_clip_rect(pos.x + gw, pos.y, self.size.x, self.size.y)
for i = minline, maxline do
self:draw_line_body(i, x, y)
y = y + lh
end
core.pop_clip_rect()
self:draw_scrollbar()
end
return DocView

480
vendor/lite/data/core/init.lua vendored Normal file
View file

@ -0,0 +1,480 @@
require "core.strict"
local common = require "core.common"
local config = require "core.config"
local style = require "core.style"
local command
local keymap
local RootView
local StatusView
local CommandView
local Doc
local core = {}
local function project_scan_thread()
local function diff_files(a, b)
if #a ~= #b then return true end
for i, v in ipairs(a) do
if b[i].filename ~= v.filename
or b[i].modified ~= v.modified then
return true
end
end
end
local function compare_file(a, b)
return a.filename < b.filename
end
local function get_files(path, t)
coroutine.yield()
t = t or {}
local size_limit = config.file_size_limit * 10e5
local all = system.list_dir(path) or {}
local dirs, files = {}, {}
for _, file in ipairs(all) do
if not common.match_pattern(file, config.ignore_files) then
local file = (path ~= "." and path .. PATHSEP or "") .. file
local info = system.get_file_info(file)
if info and info.size < size_limit then
info.filename = file
table.insert(info.type == "dir" and dirs or files, info)
end
end
end
table.sort(dirs, compare_file)
for _, f in ipairs(dirs) do
table.insert(t, f)
get_files(f.filename, t)
end
table.sort(files, compare_file)
for _, f in ipairs(files) do
table.insert(t, f)
end
return t
end
while true do
-- get project files and replace previous table if the new table is
-- different
local t = get_files(".")
if diff_files(core.project_files, t) then
core.project_files = t
core.redraw = true
end
-- wait for next scan
coroutine.yield(config.project_scan_rate)
end
end
function core.init()
command = require "core.command"
keymap = require "core.keymap"
RootView = require "core.rootview"
StatusView = require "core.statusview"
CommandView = require "core.commandview"
Doc = require "core.doc"
local project_dir = EXEDIR
local files = {}
for i = 2, #ARGS do
local info = system.get_file_info(ARGS[i]) or {}
if info.type == "file" then
table.insert(files, system.absolute_path(ARGS[i]))
elseif info.type == "dir" then
project_dir = ARGS[i]
end
end
system.chdir(project_dir)
core.frame_start = 0
core.clip_rect_stack = {{ 0,0,0,0 }}
core.log_items = {}
core.docs = {}
core.threads = setmetatable({}, { __mode = "k" })
core.project_files = {}
core.redraw = true
core.root_view = RootView()
core.command_view = CommandView()
core.status_view = StatusView()
core.root_view.root_node:split("down", core.command_view, true)
core.root_view.root_node.b:split("down", core.status_view, true)
core.add_thread(project_scan_thread)
command.add_defaults()
local got_plugin_error = not core.load_plugins()
local got_user_error = not core.try(require, "user")
local got_project_error = not core.load_project_module()
for _, filename in ipairs(files) do
core.root_view:open_doc(core.open_doc(filename))
end
if got_plugin_error or got_user_error or got_project_error then
command.perform("core:open-log")
end
end
local temp_uid = (system.get_time() * 1000) % 0xffffffff
local temp_file_prefix = string.format(".lite_temp_%08x", temp_uid)
local temp_file_counter = 0
local function delete_temp_files()
for _, filename in ipairs(system.list_dir(EXEDIR)) do
if filename:find(temp_file_prefix, 1, true) == 1 then
os.remove(EXEDIR .. PATHSEP .. filename)
end
end
end
function core.temp_filename(ext)
temp_file_counter = temp_file_counter + 1
return EXEDIR .. PATHSEP .. temp_file_prefix
.. string.format("%06x", temp_file_counter) .. (ext or "")
end
function core.quit(force)
if force then
delete_temp_files()
os.exit()
end
local dirty_count = 0
local dirty_name
for _, doc in ipairs(core.docs) do
if doc:is_dirty() then
dirty_count = dirty_count + 1
dirty_name = doc:get_name()
end
end
if dirty_count > 0 then
local text
if dirty_count == 1 then
text = string.format("\"%s\" has unsaved changes. Quit anyway?", dirty_name)
else
text = string.format("%d docs have unsaved changes. Quit anyway?", dirty_count)
end
local confirm = system.show_confirm_dialog("Unsaved Changes", text)
if not confirm then return end
end
core.quit(true)
end
function core.load_plugins()
local no_errors = true
local files = system.list_dir(EXEDIR .. "/data/plugins")
for _, filename in ipairs(files) do
local modname = "plugins." .. filename:gsub(".lua$", "")
local ok = core.try(require, modname)
if ok then
core.log_quiet("Loaded plugin %q", modname)
else
no_errors = false
end
end
return no_errors
end
function core.load_project_module()
local filename = ".lite_project.lua"
if system.get_file_info(filename) then
return core.try(function()
local fn, err = loadfile(filename)
if not fn then error("Error when loading project module:\n\t" .. err) end
fn()
core.log_quiet("Loaded project module")
end)
end
return true
end
function core.reload_module(name)
local old = package.loaded[name]
package.loaded[name] = nil
local new = require(name)
if type(old) == "table" then
for k, v in pairs(new) do old[k] = v end
package.loaded[name] = old
end
end
function core.set_active_view(view)
assert(view, "Tried to set active view to nil")
if view ~= core.active_view then
core.last_active_view = core.active_view
core.active_view = view
end
end
function core.add_thread(f, weak_ref)
local key = weak_ref or #core.threads + 1
local fn = function() return core.try(f) end
core.threads[key] = { cr = coroutine.create(fn), wake = 0 }
end
function core.push_clip_rect(x, y, w, h)
local x2, y2, w2, h2 = table.unpack(core.clip_rect_stack[#core.clip_rect_stack])
local r, b, r2, b2 = x+w, y+h, x2+w2, y2+h2
x, y = math.max(x, x2), math.max(y, y2)
b, r = math.min(b, b2), math.min(r, r2)
w, h = r-x, b-y
table.insert(core.clip_rect_stack, { x, y, w, h })
renderer.set_clip_rect(x, y, w, h)
end
function core.pop_clip_rect()
table.remove(core.clip_rect_stack)
local x, y, w, h = table.unpack(core.clip_rect_stack[#core.clip_rect_stack])
renderer.set_clip_rect(x, y, w, h)
end
function core.open_doc(filename)
if filename then
-- try to find existing doc for filename
local abs_filename = system.absolute_path(filename)
for _, doc in ipairs(core.docs) do
if doc.filename
and abs_filename == system.absolute_path(doc.filename) then
return doc
end
end
end
-- no existing doc for filename; create new
local doc = Doc(filename)
table.insert(core.docs, doc)
core.log_quiet(filename and "Opened doc \"%s\"" or "Opened new doc", filename)
return doc
end
function core.get_views_referencing_doc(doc)
local res = {}
local views = core.root_view.root_node:get_children()
for _, view in ipairs(views) do
if view.doc == doc then table.insert(res, view) end
end
return res
end
local function log(icon, icon_color, fmt, ...)
local text = string.format(fmt, ...)
if icon then
core.status_view:show_message(icon, icon_color, text)
end
local info = debug.getinfo(2, "Sl")
local at = string.format("%s:%d", info.short_src, info.currentline)
local item = { text = text, time = os.time(), at = at }
table.insert(core.log_items, item)
if #core.log_items > config.max_log_items then
table.remove(core.log_items, 1)
end
return item
end
function core.log(...)
return log("i", style.text, ...)
end
function core.log_quiet(...)
return log(nil, nil, ...)
end
function core.error(...)
return log("!", style.accent, ...)
end
function core.try(fn, ...)
local err
local ok, res = xpcall(fn, function(msg)
local item = core.error("%s", msg)
item.info = debug.traceback(nil, 2):gsub("\t", "")
err = msg
end, ...)
if ok then
return true, res
end
return false, err
end
function core.on_event(type, ...)
local did_keymap = false
if type == "textinput" then
core.root_view:on_text_input(...)
elseif type == "keypressed" then
did_keymap = keymap.on_key_pressed(...)
elseif type == "keyreleased" then
keymap.on_key_released(...)
elseif type == "mousemoved" then
core.root_view:on_mouse_moved(...)
elseif type == "mousepressed" then
core.root_view:on_mouse_pressed(...)
elseif type == "mousereleased" then
core.root_view:on_mouse_released(...)
elseif type == "mousewheel" then
core.root_view:on_mouse_wheel(...)
elseif type == "filedropped" then
local filename, mx, my = ...
local info = system.get_file_info(filename)
if info and info.type == "dir" then
system.exec(string.format("%q %q", EXEFILE, filename))
else
local ok, doc = core.try(core.open_doc, filename)
if ok then
local node = core.root_view.root_node:get_child_overlapping_point(mx, my)
node:set_active_view(node.active_view)
core.root_view:open_doc(doc)
end
end
elseif type == "quit" then
core.quit()
end
return did_keymap
end
function core.step()
-- handle events
local did_keymap = false
local mouse_moved = false
local mouse = { x = 0, y = 0, dx = 0, dy = 0 }
for type, a,b,c,d in system.poll_event do
if type == "mousemoved" then
mouse_moved = true
mouse.x, mouse.y = a, b
mouse.dx, mouse.dy = mouse.dx + c, mouse.dy + d
elseif type == "textinput" and did_keymap then
did_keymap = false
else
local _, res = core.try(core.on_event, type, a, b, c, d)
did_keymap = res or did_keymap
end
core.redraw = true
end
if mouse_moved then
core.try(core.on_event, "mousemoved", mouse.x, mouse.y, mouse.dx, mouse.dy)
end
local width, height = renderer.get_size()
-- update
core.root_view.size.x, core.root_view.size.y = width, height
core.root_view:update()
if not core.redraw then return false end
core.redraw = false
-- close unreferenced docs
for i = #core.docs, 1, -1 do
local doc = core.docs[i]
if #core.get_views_referencing_doc(doc) == 0 then
table.remove(core.docs, i)
core.log_quiet("Closed doc \"%s\"", doc:get_name())
end
end
-- update window title
local name = core.active_view:get_name()
local title = (name ~= "---") and (name .. " - lite") or "lite"
if title ~= core.window_title then
system.set_window_title(title)
core.window_title = title
end
-- draw
renderer.begin_frame()
core.clip_rect_stack[1] = { 0, 0, width, height }
renderer.set_clip_rect(table.unpack(core.clip_rect_stack[1]))
core.root_view:draw()
renderer.end_frame()
return true
end
core.run_threads = coroutine.wrap(function()
while true do
local max_time = 1 / config.fps - 0.004
local ran_any_threads = false
for k, thread in pairs(core.threads) do
-- run thread
if thread.wake < system.get_time() then
local _, wait = assert(coroutine.resume(thread.cr))
if coroutine.status(thread.cr) == "dead" then
if type(k) == "number" then
table.remove(core.threads, k)
else
core.threads[k] = nil
end
elseif wait then
thread.wake = system.get_time() + wait
end
ran_any_threads = true
end
-- stop running threads if we're about to hit the end of frame
if system.get_time() - core.frame_start > max_time then
coroutine.yield()
end
end
if not ran_any_threads then coroutine.yield() end
end
end)
function core.run()
while true do
core.frame_start = system.get_time()
local did_redraw = core.step()
core.run_threads()
if not did_redraw and not system.window_has_focus() then
system.wait_event(0.25)
end
local elapsed = system.get_time() - core.frame_start
system.sleep(math.max(0, 1 / config.fps - elapsed))
end
end
function core.on_error(err)
-- write error to file
local fp = io.open(EXEDIR .. "/error.txt", "wb")
fp:write("Error: " .. tostring(err) .. "\n")
fp:write(debug.traceback(nil, 4))
fp:close()
-- save copy of all unsaved documents
for _, doc in ipairs(core.docs) do
if doc:is_dirty() and doc.filename then
doc:save(doc.filename .. "~")
end
end
end
return core

186
vendor/lite/data/core/keymap.lua vendored Normal file
View file

@ -0,0 +1,186 @@
local command = require "core.command"
local keymap = {}
keymap.modkeys = {}
keymap.map = {}
keymap.reverse_map = {}
local modkey_map = {
["left ctrl"] = "ctrl",
["right ctrl"] = "ctrl",
["left shift"] = "shift",
["right shift"] = "shift",
["left alt"] = "alt",
["right alt"] = "altgr",
}
local modkeys = { "ctrl", "alt", "altgr", "shift" }
local function key_to_stroke(k)
local stroke = ""
for _, mk in ipairs(modkeys) do
if keymap.modkeys[mk] then
stroke = stroke .. mk .. "+"
end
end
return stroke .. k
end
function keymap.add(map, overwrite)
for stroke, commands in pairs(map) do
if type(commands) == "string" then
commands = { commands }
end
if overwrite then
keymap.map[stroke] = commands
else
keymap.map[stroke] = keymap.map[stroke] or {}
for i = #commands, 1, -1 do
table.insert(keymap.map[stroke], 1, commands[i])
end
end
for _, cmd in ipairs(commands) do
keymap.reverse_map[cmd] = stroke
end
end
end
function keymap.get_binding(cmd)
return keymap.reverse_map[cmd]
end
function keymap.on_key_pressed(k)
local mk = modkey_map[k]
if mk then
keymap.modkeys[mk] = true
-- work-around for windows where `altgr` is treated as `ctrl+alt`
if mk == "altgr" then
keymap.modkeys["ctrl"] = false
end
else
local stroke = key_to_stroke(k)
local commands = keymap.map[stroke]
if commands then
for _, cmd in ipairs(commands) do
local performed = command.perform(cmd)
if performed then break end
end
return true
end
end
return false
end
function keymap.on_key_released(k)
local mk = modkey_map[k]
if mk then
keymap.modkeys[mk] = false
end
end
keymap.add {
["ctrl+shift+p"] = "core:find-command",
["ctrl+p"] = "core:find-file",
["ctrl+o"] = "core:open-file",
["ctrl+n"] = "core:new-doc",
["alt+return"] = "core:toggle-fullscreen",
["alt+shift+j"] = "root:split-left",
["alt+shift+l"] = "root:split-right",
["alt+shift+i"] = "root:split-up",
["alt+shift+k"] = "root:split-down",
["alt+j"] = "root:switch-to-left",
["alt+l"] = "root:switch-to-right",
["alt+i"] = "root:switch-to-up",
["alt+k"] = "root:switch-to-down",
["ctrl+w"] = "root:close",
["ctrl+tab"] = "root:switch-to-next-tab",
["ctrl+shift+tab"] = "root:switch-to-previous-tab",
["ctrl+pageup"] = "root:move-tab-left",
["ctrl+pagedown"] = "root:move-tab-right",
["alt+1"] = "root:switch-to-tab-1",
["alt+2"] = "root:switch-to-tab-2",
["alt+3"] = "root:switch-to-tab-3",
["alt+4"] = "root:switch-to-tab-4",
["alt+5"] = "root:switch-to-tab-5",
["alt+6"] = "root:switch-to-tab-6",
["alt+7"] = "root:switch-to-tab-7",
["alt+8"] = "root:switch-to-tab-8",
["alt+9"] = "root:switch-to-tab-9",
["ctrl+f"] = "find-replace:find",
["ctrl+r"] = "find-replace:replace",
["f3"] = "find-replace:repeat-find",
["shift+f3"] = "find-replace:previous-find",
["ctrl+g"] = "doc:go-to-line",
["ctrl+s"] = "doc:save",
["ctrl+shift+s"] = "doc:save-as",
["ctrl+z"] = "doc:undo",
["ctrl+y"] = "doc:redo",
["ctrl+x"] = "doc:cut",
["ctrl+c"] = "doc:copy",
["ctrl+v"] = "doc:paste",
["escape"] = { "command:escape", "doc:select-none" },
["tab"] = { "command:complete", "doc:indent" },
["shift+tab"] = "doc:unindent",
["backspace"] = "doc:backspace",
["shift+backspace"] = "doc:backspace",
["ctrl+backspace"] = "doc:delete-to-previous-word-start",
["ctrl+shift+backspace"] = "doc:delete-to-previous-word-start",
["delete"] = "doc:delete",
["shift+delete"] = "doc:delete",
["ctrl+delete"] = "doc:delete-to-next-word-end",
["ctrl+shift+delete"] = "doc:delete-to-next-word-end",
["return"] = { "command:submit", "doc:newline" },
["keypad enter"] = { "command:submit", "doc:newline" },
["ctrl+return"] = "doc:newline-below",
["ctrl+shift+return"] = "doc:newline-above",
["ctrl+j"] = "doc:join-lines",
["ctrl+a"] = "doc:select-all",
["ctrl+d"] = { "find-replace:select-next", "doc:select-word" },
["ctrl+l"] = "doc:select-lines",
["ctrl+/"] = "doc:toggle-line-comments",
["ctrl+up"] = "doc:move-lines-up",
["ctrl+down"] = "doc:move-lines-down",
["ctrl+shift+d"] = "doc:duplicate-lines",
["ctrl+shift+k"] = "doc:delete-lines",
["left"] = "doc:move-to-previous-char",
["right"] = "doc:move-to-next-char",
["up"] = { "command:select-previous", "doc:move-to-previous-line" },
["down"] = { "command:select-next", "doc:move-to-next-line" },
["ctrl+left"] = "doc:move-to-previous-word-start",
["ctrl+right"] = "doc:move-to-next-word-end",
["ctrl+["] = "doc:move-to-previous-block-start",
["ctrl+]"] = "doc:move-to-next-block-end",
["home"] = "doc:move-to-start-of-line",
["end"] = "doc:move-to-end-of-line",
["ctrl+home"] = "doc:move-to-start-of-doc",
["ctrl+end"] = "doc:move-to-end-of-doc",
["pageup"] = "doc:move-to-previous-page",
["pagedown"] = "doc:move-to-next-page",
["shift+left"] = "doc:select-to-previous-char",
["shift+right"] = "doc:select-to-next-char",
["shift+up"] = "doc:select-to-previous-line",
["shift+down"] = "doc:select-to-next-line",
["ctrl+shift+left"] = "doc:select-to-previous-word-start",
["ctrl+shift+right"] = "doc:select-to-next-word-end",
["ctrl+shift+["] = "doc:select-to-previous-block-start",
["ctrl+shift+]"] = "doc:select-to-next-block-end",
["shift+home"] = "doc:select-to-start-of-line",
["shift+end"] = "doc:select-to-end-of-line",
["ctrl+shift+home"] = "doc:select-to-start-of-doc",
["ctrl+shift+end"] = "doc:select-to-end-of-doc",
["shift+pageup"] = "doc:select-to-previous-page",
["shift+pagedown"] = "doc:select-to-next-page",
}
return keymap

74
vendor/lite/data/core/logview.lua vendored Normal file
View file

@ -0,0 +1,74 @@
local core = require "core"
local style = require "core.style"
local View = require "core.view"
local LogView = View:extend()
function LogView:new()
LogView.super.new(self)
self.last_item = core.log_items[#core.log_items]
self.scrollable = true
self.yoffset = 0
end
function LogView:get_name()
return "Log"
end
function LogView:update()
local item = core.log_items[#core.log_items]
if self.last_item ~= item then
self.last_item = item
self.scroll.to.y = 0
self.yoffset = -(style.font:get_height() + style.padding.y)
end
self:move_towards("yoffset", 0)
LogView.super.update(self)
end
local function draw_text_multiline(font, text, x, y, color)
local th = font:get_height()
local resx, resy = x, y
for line in text:gmatch("[^\n]+") do
resy = y
resx = renderer.draw_text(style.font, line, x, y, color)
y = y + th
end
return resx, resy
end
function LogView:draw()
self:draw_background(style.background)
local ox, oy = self:get_content_offset()
local th = style.font:get_height()
local y = oy + style.padding.y + self.yoffset
for i = #core.log_items, 1, -1 do
local x = ox + style.padding.x
local item = core.log_items[i]
local time = os.date(nil, item.time)
x = renderer.draw_text(style.font, time, x, y, style.dim)
x = x + style.padding.x
local subx = x
x, y = draw_text_multiline(style.font, item.text, x, y, style.text)
renderer.draw_text(style.font, " at " .. item.at, x, y, style.dim)
y = y + th
if item.info then
subx, y = draw_text_multiline(style.font, item.info, subx, y, style.dim)
y = y + th
end
y = y + style.padding.y
end
end
return LogView

58
vendor/lite/data/core/object.lua vendored Normal file
View file

@ -0,0 +1,58 @@
local Object = {}
Object.__index = Object
function Object:new()
end
function Object:extend()
local cls = {}
for k, v in pairs(self) do
if k:find("__") == 1 then
cls[k] = v
end
end
cls.__index = cls
cls.super = self
setmetatable(cls, self)
return cls
end
function Object:implement(...)
for _, cls in pairs({...}) do
for k, v in pairs(cls) do
if self[k] == nil and type(v) == "function" then
self[k] = v
end
end
end
end
function Object:is(T)
local mt = getmetatable(self)
while mt do
if mt == T then
return true
end
mt = getmetatable(mt)
end
return false
end
function Object:__tostring()
return "Object"
end
function Object:__call(...)
local obj = setmetatable({}, self)
obj:new(...)
return obj
end
return Object

504
vendor/lite/data/core/rootview.lua vendored Normal file
View file

@ -0,0 +1,504 @@
local core = require "core"
local common = require "core.common"
local style = require "core.style"
local keymap = require "core.keymap"
local Object = require "core.object"
local View = require "core.view"
local DocView = require "core.docview"
local EmptyView = View:extend()
local function draw_text(x, y, color)
local th = style.big_font:get_height()
local dh = th + style.padding.y * 2
x = renderer.draw_text(style.big_font, "lite", x, y + (dh - th) / 2, color)
x = x + style.padding.x
renderer.draw_rect(x, y, math.ceil(1 * SCALE), dh, color)
local lines = {
{ fmt = "%s to run a command", cmd = "core:find-command" },
{ fmt = "%s to open a file from the project", cmd = "core:find-file" },
}
th = style.font:get_height()
y = y + (dh - th * 2 - style.padding.y) / 2
local w = 0
for _, line in ipairs(lines) do
local text = string.format(line.fmt, keymap.get_binding(line.cmd))
w = math.max(w, renderer.draw_text(style.font, text, x + style.padding.x, y, color))
y = y + th + style.padding.y
end
return w, dh
end
function EmptyView:draw()
self:draw_background(style.background)
local w, h = draw_text(0, 0, { 0, 0, 0, 0 })
local x = self.position.x + math.max(style.padding.x, (self.size.x - w) / 2)
local y = self.position.y + (self.size.y - h) / 2
draw_text(x, y, style.dim)
end
local Node = Object:extend()
function Node:new(type)
self.type = type or "leaf"
self.position = { x = 0, y = 0 }
self.size = { x = 0, y = 0 }
self.views = {}
self.divider = 0.5
if self.type == "leaf" then
self:add_view(EmptyView())
end
end
function Node:propagate(fn, ...)
self.a[fn](self.a, ...)
self.b[fn](self.b, ...)
end
function Node:on_mouse_moved(x, y, ...)
self.hovered_tab = self:get_tab_overlapping_point(x, y)
if self.type == "leaf" then
self.active_view:on_mouse_moved(x, y, ...)
else
self:propagate("on_mouse_moved", x, y, ...)
end
end
function Node:on_mouse_released(...)
if self.type == "leaf" then
self.active_view:on_mouse_released(...)
else
self:propagate("on_mouse_released", ...)
end
end
function Node:consume(node)
for k, _ in pairs(self) do self[k] = nil end
for k, v in pairs(node) do self[k] = v end
end
local type_map = { up="vsplit", down="vsplit", left="hsplit", right="hsplit" }
function Node:split(dir, view, locked)
assert(self.type == "leaf", "Tried to split non-leaf node")
local type = assert(type_map[dir], "Invalid direction")
local last_active = core.active_view
local child = Node()
child:consume(self)
self:consume(Node(type))
self.a = child
self.b = Node()
if view then self.b:add_view(view) end
if locked then
self.b.locked = locked
core.set_active_view(last_active)
end
if dir == "up" or dir == "left" then
self.a, self.b = self.b, self.a
end
return child
end
function Node:close_active_view(root)
local do_close = function()
if #self.views > 1 then
local idx = self:get_view_idx(self.active_view)
table.remove(self.views, idx)
self:set_active_view(self.views[idx] or self.views[#self.views])
else
local parent = self:get_parent_node(root)
local is_a = (parent.a == self)
local other = parent[is_a and "b" or "a"]
if other:get_locked_size() then
self.views = {}
self:add_view(EmptyView())
else
parent:consume(other)
local p = parent
while p.type ~= "leaf" do
p = p[is_a and "a" or "b"]
end
p:set_active_view(p.active_view)
end
end
core.last_active_view = nil
end
self.active_view:try_close(do_close)
end
function Node:add_view(view)
assert(self.type == "leaf", "Tried to add view to non-leaf node")
assert(not self.locked, "Tried to add view to locked node")
if self.views[1] and self.views[1]:is(EmptyView) then
table.remove(self.views)
end
table.insert(self.views, view)
self:set_active_view(view)
end
function Node:set_active_view(view)
assert(self.type == "leaf", "Tried to set active view on non-leaf node")
self.active_view = view
core.set_active_view(view)
end
function Node:get_view_idx(view)
for i, v in ipairs(self.views) do
if v == view then return i end
end
end
function Node:get_node_for_view(view)
for _, v in ipairs(self.views) do
if v == view then return self end
end
if self.type ~= "leaf" then
return self.a:get_node_for_view(view) or self.b:get_node_for_view(view)
end
end
function Node:get_parent_node(root)
if root.a == self or root.b == self then
return root
elseif root.type ~= "leaf" then
return self:get_parent_node(root.a) or self:get_parent_node(root.b)
end
end
function Node:get_children(t)
t = t or {}
for _, view in ipairs(self.views) do
table.insert(t, view)
end
if self.a then self.a:get_children(t) end
if self.b then self.b:get_children(t) end
return t
end
function Node:get_divider_overlapping_point(px, py)
if self.type ~= "leaf" then
local p = 6
local x, y, w, h = self:get_divider_rect()
x, y = x - p, y - p
w, h = w + p * 2, h + p * 2
if px > x and py > y and px < x + w and py < y + h then
return self
end
return self.a:get_divider_overlapping_point(px, py)
or self.b:get_divider_overlapping_point(px, py)
end
end
function Node:get_tab_overlapping_point(px, py)
if #self.views == 1 then return nil end
local x, y, w, h = self:get_tab_rect(1)
if px >= x and py >= y and px < x + w * #self.views and py < y + h then
return math.floor((px - x) / w) + 1
end
end
function Node:get_child_overlapping_point(x, y)
local child
if self.type == "leaf" then
return self
elseif self.type == "hsplit" then
child = (x < self.b.position.x) and self.a or self.b
elseif self.type == "vsplit" then
child = (y < self.b.position.y) and self.a or self.b
end
return child:get_child_overlapping_point(x, y)
end
function Node:get_tab_rect(idx)
local tw = math.min(style.tab_width, math.ceil(self.size.x / #self.views))
local h = style.font:get_height() + style.padding.y * 2
return self.position.x + (idx-1) * tw, self.position.y, tw, h
end
function Node:get_divider_rect()
local x, y = self.position.x, self.position.y
if self.type == "hsplit" then
return x + self.a.size.x, y, style.divider_size, self.size.y
elseif self.type == "vsplit" then
return x, y + self.a.size.y, self.size.x, style.divider_size
end
end
function Node:get_locked_size()
if self.type == "leaf" then
if self.locked then
local size = self.active_view.size
return size.x, size.y
end
else
local x1, y1 = self.a:get_locked_size()
local x2, y2 = self.b:get_locked_size()
if x1 and x2 then
local dsx = (x1 < 1 or x2 < 1) and 0 or style.divider_size
local dsy = (y1 < 1 or y2 < 1) and 0 or style.divider_size
return x1 + x2 + dsx, y1 + y2 + dsy
end
end
end
local function copy_position_and_size(dst, src)
dst.position.x, dst.position.y = src.position.x, src.position.y
dst.size.x, dst.size.y = src.size.x, src.size.y
end
-- calculating the sizes is the same for hsplits and vsplits, except the x/y
-- axis are swapped; this function lets us use the same code for both
local function calc_split_sizes(self, x, y, x1, x2)
local n
local ds = (x1 and x1 < 1 or x2 and x2 < 1) and 0 or style.divider_size
if x1 then
n = x1 + ds
elseif x2 then
n = self.size[x] - x2
else
n = math.floor(self.size[x] * self.divider)
end
self.a.position[x] = self.position[x]
self.a.position[y] = self.position[y]
self.a.size[x] = n - ds
self.a.size[y] = self.size[y]
self.b.position[x] = self.position[x] + n
self.b.position[y] = self.position[y]
self.b.size[x] = self.size[x] - n
self.b.size[y] = self.size[y]
end
function Node:update_layout()
if self.type == "leaf" then
local av = self.active_view
if #self.views > 1 then
local _, _, _, th = self:get_tab_rect(1)
av.position.x, av.position.y = self.position.x, self.position.y + th
av.size.x, av.size.y = self.size.x, self.size.y - th
else
copy_position_and_size(av, self)
end
else
local x1, y1 = self.a:get_locked_size()
local x2, y2 = self.b:get_locked_size()
if self.type == "hsplit" then
calc_split_sizes(self, "x", "y", x1, x2)
elseif self.type == "vsplit" then
calc_split_sizes(self, "y", "x", y1, y2)
end
self.a:update_layout()
self.b:update_layout()
end
end
function Node:update()
if self.type == "leaf" then
for _, view in ipairs(self.views) do
view:update()
end
else
self.a:update()
self.b:update()
end
end
function Node:draw_tabs()
local x, y, _, h = self:get_tab_rect(1)
local ds = style.divider_size
core.push_clip_rect(x, y, self.size.x, h)
renderer.draw_rect(x, y, self.size.x, h, style.background2)
renderer.draw_rect(x, y + h - ds, self.size.x, ds, style.divider)
for i, view in ipairs(self.views) do
local x, y, w, h = self:get_tab_rect(i)
local text = view:get_name()
local color = style.dim
if view == self.active_view then
color = style.text
renderer.draw_rect(x, y, w, h, style.background)
renderer.draw_rect(x + w, y, ds, h, style.divider)
renderer.draw_rect(x - ds, y, ds, h, style.divider)
end
if i == self.hovered_tab then
color = style.text
end
core.push_clip_rect(x, y, w, h)
x, w = x + style.padding.x, w - style.padding.x * 2
local align = style.font:get_width(text) > w and "left" or "center"
common.draw_text(style.font, color, text, align, x, y, w, h)
core.pop_clip_rect()
end
core.pop_clip_rect()
end
function Node:draw()
if self.type == "leaf" then
if #self.views > 1 then
self:draw_tabs()
end
local pos, size = self.active_view.position, self.active_view.size
core.push_clip_rect(pos.x, pos.y, size.x + pos.x % 1, size.y + pos.y % 1)
self.active_view:draw()
core.pop_clip_rect()
else
local x, y, w, h = self:get_divider_rect()
renderer.draw_rect(x, y, w, h, style.divider)
self:propagate("draw")
end
end
local RootView = View:extend()
function RootView:new()
RootView.super.new(self)
self.root_node = Node()
self.deferred_draws = {}
self.mouse = { x = 0, y = 0 }
end
function RootView:defer_draw(fn, ...)
table.insert(self.deferred_draws, 1, { fn = fn, ... })
end
function RootView:get_active_node()
return self.root_node:get_node_for_view(core.active_view)
end
function RootView:open_doc(doc)
local node = self:get_active_node()
if node.locked and core.last_active_view then
core.set_active_view(core.last_active_view)
node = self:get_active_node()
end
assert(not node.locked, "Cannot open doc on locked node")
for i, view in ipairs(node.views) do
if view.doc == doc then
node:set_active_view(node.views[i])
return view
end
end
local view = DocView(doc)
node:add_view(view)
self.root_node:update_layout()
view:scroll_to_line(view.doc:get_selection(), true, true)
return view
end
function RootView:on_mouse_pressed(button, x, y, clicks)
local div = self.root_node:get_divider_overlapping_point(x, y)
if div then
self.dragged_divider = div
return
end
local node = self.root_node:get_child_overlapping_point(x, y)
local idx = node:get_tab_overlapping_point(x, y)
if idx then
node:set_active_view(node.views[idx])
if button == "middle" then
node:close_active_view(self.root_node)
end
else
core.set_active_view(node.active_view)
node.active_view:on_mouse_pressed(button, x, y, clicks)
end
end
function RootView:on_mouse_released(...)
if self.dragged_divider then
self.dragged_divider = nil
end
self.root_node:on_mouse_released(...)
end
function RootView:on_mouse_moved(x, y, dx, dy)
if self.dragged_divider then
local node = self.dragged_divider
if node.type == "hsplit" then
node.divider = node.divider + dx / node.size.x
else
node.divider = node.divider + dy / node.size.y
end
node.divider = common.clamp(node.divider, 0.01, 0.99)
return
end
self.mouse.x, self.mouse.y = x, y
self.root_node:on_mouse_moved(x, y, dx, dy)
local node = self.root_node:get_child_overlapping_point(x, y)
local div = self.root_node:get_divider_overlapping_point(x, y)
if div then
system.set_cursor(div.type == "hsplit" and "sizeh" or "sizev")
elseif node:get_tab_overlapping_point(x, y) then
system.set_cursor("arrow")
else
system.set_cursor(node.active_view.cursor)
end
end
function RootView:on_mouse_wheel(...)
local x, y = self.mouse.x, self.mouse.y
local node = self.root_node:get_child_overlapping_point(x, y)
node.active_view:on_mouse_wheel(...)
end
function RootView:on_text_input(...)
core.active_view:on_text_input(...)
end
function RootView:update()
copy_position_and_size(self.root_node, self)
self.root_node:update()
self.root_node:update_layout()
end
function RootView:draw()
self.root_node:draw()
while #self.deferred_draws > 0 do
local t = table.remove(self.deferred_draws)
t.fn(table.unpack(t))
end
end
return RootView

141
vendor/lite/data/core/statusview.lua vendored Normal file
View file

@ -0,0 +1,141 @@
local core = require "core"
local common = require "core.common"
local command = require "core.command"
local config = require "core.config"
local style = require "core.style"
local DocView = require "core.docview"
local LogView = require "core.logview"
local View = require "core.view"
local StatusView = View:extend()
StatusView.separator = " "
StatusView.separator2 = " | "
function StatusView:new()
StatusView.super.new(self)
self.message_timeout = 0
self.message = {}
end
function StatusView:on_mouse_pressed()
core.set_active_view(core.last_active_view)
if system.get_time() < self.message_timeout
and not core.active_view:is(LogView) then
command.perform "core:open-log"
end
end
function StatusView:show_message(icon, icon_color, text)
self.message = {
icon_color, style.icon_font, icon,
style.dim, style.font, StatusView.separator2, style.text, text
}
self.message_timeout = system.get_time() + config.message_timeout
end
function StatusView:update()
self.size.y = style.font:get_height() + style.padding.y * 2
if system.get_time() < self.message_timeout then
self.scroll.to.y = self.size.y
else
self.scroll.to.y = 0
end
StatusView.super.update(self)
end
local function draw_items(self, items, x, y, draw_fn)
local font = style.font
local color = style.text
for _, item in ipairs(items) do
if type(item) == "userdata" then
font = item
elseif type(item) == "table" then
color = item
else
x = draw_fn(font, color, item, nil, x, y, 0, self.size.y)
end
end
return x
end
local function text_width(font, _, text, _, x)
return x + font:get_width(text)
end
function StatusView:draw_items(items, right_align, yoffset)
local x, y = self:get_content_offset()
y = y + (yoffset or 0)
if right_align then
local w = draw_items(self, items, 0, 0, text_width)
x = x + self.size.x - w - style.padding.x
draw_items(self, items, x, y, common.draw_text)
else
x = x + style.padding.x
draw_items(self, items, x, y, common.draw_text)
end
end
function StatusView:get_items()
if getmetatable(core.active_view) == DocView then
local dv = core.active_view
local line, col = dv.doc:get_selection()
local dirty = dv.doc:is_dirty()
return {
dirty and style.accent or style.text, style.icon_font, "f",
style.dim, style.font, self.separator2, style.text,
dv.doc.filename and style.text or style.dim, dv.doc:get_name(),
style.text,
self.separator,
"line: ", line,
self.separator,
col > config.line_limit and style.accent or style.text, "col: ", col,
style.text,
self.separator,
string.format("%d%%", line / #dv.doc.lines * 100),
}, {
style.icon_font, "g",
style.font, style.dim, self.separator2, style.text,
#dv.doc.lines, " lines",
self.separator,
dv.doc.crlf and "CRLF" or "LF"
}
end
return {}, {
style.icon_font, "g",
style.font, style.dim, self.separator2,
#core.docs, style.text, " / ",
#core.project_files, " files"
}
end
function StatusView:draw()
self:draw_background(style.background2)
if self.message then
self:draw_items(self.message, false, self.size.y)
end
local left, right = self:get_items()
self:draw_items(left)
self:draw_items(right, true)
end
return StatusView

26
vendor/lite/data/core/strict.lua vendored Normal file
View file

@ -0,0 +1,26 @@
local strict = {}
strict.defined = {}
-- used to define a global variable
function global(t)
for k, v in pairs(t) do
strict.defined[k] = true
rawset(_G, k, v)
end
end
function strict.__newindex(t, k, v)
error("cannot set undefined variable: " .. k, 2)
end
function strict.__index(t, k)
if not strict.defined[k] then
error("cannot get undefined variable: " .. k, 2)
end
end
setmetatable(_G, strict)

42
vendor/lite/data/core/style.lua vendored Normal file
View file

@ -0,0 +1,42 @@
local common = require "core.common"
local style = {}
style.padding = { x = common.round(14 * SCALE), y = common.round(7 * SCALE) }
style.divider_size = common.round(1 * SCALE)
style.scrollbar_size = common.round(4 * SCALE)
style.caret_width = common.round(2 * SCALE)
style.tab_width = common.round(170 * SCALE)
style.font = renderer.font.load(EXEDIR .. "/data/fonts/font.ttf", 14 * SCALE)
style.big_font = renderer.font.load(EXEDIR .. "/data/fonts/font.ttf", 34 * SCALE)
style.icon_font = renderer.font.load(EXEDIR .. "/data/fonts/icons.ttf", 14 * SCALE)
style.code_font = renderer.font.load(EXEDIR .. "/data/fonts/monospace.ttf", 13.5 * SCALE)
style.background = { common.color "#2e2e32" }
style.background2 = { common.color "#252529" }
style.background3 = { common.color "#252529" }
style.text = { common.color "#97979c" }
style.caret = { common.color "#93DDFA" }
style.accent = { common.color "#e1e1e6" }
style.dim = { common.color "#525257" }
style.divider = { common.color "#202024" }
style.selection = { common.color "#48484f" }
style.line_number = { common.color "#525259" }
style.line_number2 = { common.color "#83838f" }
style.line_highlight = { common.color "#343438" }
style.scrollbar = { common.color "#414146" }
style.scrollbar2 = { common.color "#4b4b52" }
style.syntax = {}
style.syntax["normal"] = { common.color "#e1e1e6" }
style.syntax["symbol"] = { common.color "#e1e1e6" }
style.syntax["comment"] = { common.color "#676b6f" }
style.syntax["keyword"] = { common.color "#E58AC9" }
style.syntax["keyword2"] = { common.color "#F77483" }
style.syntax["number"] = { common.color "#FFA94D" }
style.syntax["literal"] = { common.color "#FFA94D" }
style.syntax["string"] = { common.color "#f7c95c" }
style.syntax["operator"] = { common.color "#93DDFA" }
style.syntax["function"] = { common.color "#93DDFA" }
return style

30
vendor/lite/data/core/syntax.lua vendored Normal file
View file

@ -0,0 +1,30 @@
local common = require "core.common"
local syntax = {}
syntax.items = {}
local plain_text_syntax = { patterns = {}, symbols = {} }
function syntax.add(t)
table.insert(syntax.items, t)
end
local function find(string, field)
for i = #syntax.items, 1, -1 do
local t = syntax.items[i]
if common.match_pattern(string, t[field] or {}) then
return t
end
end
end
function syntax.get(filename, header)
return find(filename, "files")
or find(header, "headers")
or plain_text_syntax
end
return syntax

112
vendor/lite/data/core/tokenizer.lua vendored Normal file
View file

@ -0,0 +1,112 @@
local tokenizer = {}
local function push_token(t, type, text)
local prev_type = t[#t-1]
local prev_text = t[#t]
if prev_type and (prev_type == type or prev_text:find("^%s*$")) then
t[#t-1] = type
t[#t] = prev_text .. text
else
table.insert(t, type)
table.insert(t, text)
end
end
local function is_escaped(text, idx, esc)
local byte = esc:byte()
local count = 0
for i = idx - 1, 1, -1 do
if text:byte(i) ~= byte then break end
count = count + 1
end
return count % 2 == 1
end
local function find_non_escaped(text, pattern, offset, esc)
while true do
local s, e = text:find(pattern, offset)
if not s then break end
if esc and is_escaped(text, s, esc) then
offset = e + 1
else
return s, e
end
end
end
function tokenizer.tokenize(syntax, text, state)
local res = {}
local i = 1
if #syntax.patterns == 0 then
return { "normal", text }
end
while i <= #text do
-- continue trying to match the end pattern of a pair if we have a state set
if state then
local p = syntax.patterns[state]
local s, e = find_non_escaped(text, p.pattern[2], i, p.pattern[3])
if s then
push_token(res, p.type, text:sub(i, e))
state = nil
i = e + 1
else
push_token(res, p.type, text:sub(i))
break
end
end
-- find matching pattern
local matched = false
for n, p in ipairs(syntax.patterns) do
local pattern = (type(p.pattern) == "table") and p.pattern[1] or p.pattern
local s, e = text:find("^" .. pattern, i)
if s then
-- matched pattern; make and add token
local t = text:sub(s, e)
push_token(res, syntax.symbols[t] or p.type, t)
-- update state if this was a start|end pattern pair
if type(p.pattern) == "table" then
state = n
end
-- move cursor past this token
i = e + 1
matched = true
break
end
end
-- consume character if we didn't match
if not matched then
push_token(res, "normal", text:sub(i, i))
i = i + 1
end
end
return res, state
end
local function iter(t, i)
i = i + 2
local type, text = t[i], t[i+1]
if type then
return i, type, text
end
end
function tokenizer.each_token(t)
return iter, t, -1
end
return tokenizer

151
vendor/lite/data/core/view.lua vendored Normal file
View file

@ -0,0 +1,151 @@
local core = require "core"
local config = require "core.config"
local style = require "core.style"
local common = require "core.common"
local Object = require "core.object"
local View = Object:extend()
function View:new()
self.position = { x = 0, y = 0 }
self.size = { x = 0, y = 0 }
self.scroll = { x = 0, y = 0, to = { x = 0, y = 0 } }
self.cursor = "arrow"
self.scrollable = false
end
function View:move_towards(t, k, dest, rate)
if type(t) ~= "table" then
return self:move_towards(self, t, k, dest, rate)
end
local val = t[k]
if math.abs(val - dest) < 0.5 then
t[k] = dest
else
t[k] = common.lerp(val, dest, rate or 0.5)
end
if val ~= dest then
core.redraw = true
end
end
function View:try_close(do_close)
do_close()
end
function View:get_name()
return "---"
end
function View:get_scrollable_size()
return math.huge
end
function View:get_scrollbar_rect()
local sz = self:get_scrollable_size()
if sz <= self.size.y or sz == math.huge then
return 0, 0, 0, 0
end
local h = math.max(20, self.size.y * self.size.y / sz)
return
self.position.x + self.size.x - style.scrollbar_size,
self.position.y + self.scroll.y * (self.size.y - h) / (sz - self.size.y),
style.scrollbar_size,
h
end
function View:scrollbar_overlaps_point(x, y)
local sx, sy, sw, sh = self:get_scrollbar_rect()
return x >= sx - sw * 3 and x < sx + sw and y >= sy and y < sy + sh
end
function View:on_mouse_pressed(button, x, y, clicks)
if self:scrollbar_overlaps_point(x, y) then
self.dragging_scrollbar = true
return true
end
end
function View:on_mouse_released(button, x, y)
self.dragging_scrollbar = false
end
function View:on_mouse_moved(x, y, dx, dy)
if self.dragging_scrollbar then
local delta = self:get_scrollable_size() / self.size.y * dy
self.scroll.to.y = self.scroll.to.y + delta
end
self.hovered_scrollbar = self:scrollbar_overlaps_point(x, y)
end
function View:on_text_input(text)
-- no-op
end
function View:on_mouse_wheel(y)
if self.scrollable then
self.scroll.to.y = self.scroll.to.y + y * -config.mouse_wheel_scroll
end
end
function View:get_content_bounds()
local x = self.scroll.x
local y = self.scroll.y
return x, y, x + self.size.x, y + self.size.y
end
function View:get_content_offset()
local x = common.round(self.position.x - self.scroll.x)
local y = common.round(self.position.y - self.scroll.y)
return x, y
end
function View:clamp_scroll_position()
local max = self:get_scrollable_size() - self.size.y
self.scroll.to.y = common.clamp(self.scroll.to.y, 0, max)
end
function View:update()
self:clamp_scroll_position()
self:move_towards(self.scroll, "x", self.scroll.to.x, 0.3)
self:move_towards(self.scroll, "y", self.scroll.to.y, 0.3)
end
function View:draw_background(color)
local x, y = self.position.x, self.position.y
local w, h = self.size.x, self.size.y
renderer.draw_rect(x, y, w + x % 1, h + y % 1, color)
end
function View:draw_scrollbar()
local x, y, w, h = self:get_scrollbar_rect()
local highlight = self.hovered_scrollbar or self.dragging_scrollbar
local color = highlight and style.scrollbar2 or style.scrollbar
renderer.draw_rect(x, y, w, h, color)
end
function View:draw()
end
return View

BIN
vendor/lite/data/fonts/font.ttf vendored Normal file

Binary file not shown.

BIN
vendor/lite/data/fonts/icons.ttf vendored Normal file

Binary file not shown.

BIN
vendor/lite/data/fonts/monospace.ttf vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,284 @@
local core = require "core"
local common = require "core.common"
local config = require "core.config"
local command = require "core.command"
local style = require "core.style"
local keymap = require "core.keymap"
local translate = require "core.doc.translate"
local RootView = require "core.rootview"
local DocView = require "core.docview"
config.autocomplete_max_suggestions = 6
local autocomplete = {}
autocomplete.map = {}
local mt = { __tostring = function(t) return t.text end }
function autocomplete.add(t)
local items = {}
for text, info in pairs(t.items) do
info = (type(info) == "string") and info
table.insert(items, setmetatable({ text = text, info = info }, mt))
end
autocomplete.map[t.name] = { files = t.files or ".*", items = items }
end
core.add_thread(function()
local cache = setmetatable({}, { __mode = "k" })
local function get_symbols(doc)
local i = 1
local s = {}
while i < #doc.lines do
for sym in doc.lines[i]:gmatch(config.symbol_pattern) do
s[sym] = true
end
i = i + 1
if i % 100 == 0 then coroutine.yield() end
end
return s
end
local function cache_is_valid(doc)
local c = cache[doc]
return c and c.last_change_id == doc:get_change_id()
end
while true do
local symbols = {}
-- lift all symbols from all docs
for _, doc in ipairs(core.docs) do
-- update the cache if the doc has changed since the last iteration
if not cache_is_valid(doc) then
cache[doc] = {
last_change_id = doc:get_change_id(),
symbols = get_symbols(doc)
}
end
-- update symbol set with doc's symbol set
for sym in pairs(cache[doc].symbols) do
symbols[sym] = true
end
coroutine.yield()
end
-- update symbols list
autocomplete.add { name = "open-docs", items = symbols }
-- wait for next scan
local valid = true
while valid do
coroutine.yield(1)
for _, doc in ipairs(core.docs) do
if not cache_is_valid(doc) then
valid = false
end
end
end
end
end)
local partial = ""
local suggestions_idx = 1
local suggestions = {}
local last_line, last_col
local function reset_suggestions()
suggestions_idx = 1
suggestions = {}
end
local function update_suggestions()
local doc = core.active_view.doc
local filename = doc and doc.filename or ""
-- get all relevant suggestions for given filename
local items = {}
for _, v in pairs(autocomplete.map) do
if common.match_pattern(filename, v.files) then
for _, item in pairs(v.items) do
table.insert(items, item)
end
end
end
-- fuzzy match, remove duplicates and store
items = common.fuzzy_match(items, partial)
local j = 1
for i = 1, config.autocomplete_max_suggestions do
suggestions[i] = items[j]
while items[j] and items[i].text == items[j].text do
items[i].info = items[i].info or items[j].info
j = j + 1
end
end
end
local function get_partial_symbol()
local doc = core.active_view.doc
local line2, col2 = doc:get_selection()
local line1, col1 = doc:position_offset(line2, col2, translate.start_of_word)
return doc:get_text(line1, col1, line2, col2)
end
local function get_active_view()
if getmetatable(core.active_view) == DocView then
return core.active_view
end
end
local function get_suggestions_rect(av)
if #suggestions == 0 then
return 0, 0, 0, 0
end
local line, col = av.doc:get_selection()
local x, y = av:get_line_screen_position(line)
x = x + av:get_col_x_offset(line, col - #partial)
y = y + av:get_line_height() + style.padding.y
local font = av:get_font()
local th = font:get_height()
local max_width = 0
for _, s in ipairs(suggestions) do
local w = font:get_width(s.text)
if s.info then
w = w + style.font:get_width(s.info) + style.padding.x
end
max_width = math.max(max_width, w)
end
return
x - style.padding.x,
y - style.padding.y,
max_width + style.padding.x * 2,
#suggestions * (th + style.padding.y) + style.padding.y
end
local function draw_suggestions_box(av)
-- draw background rect
local rx, ry, rw, rh = get_suggestions_rect(av)
renderer.draw_rect(rx, ry, rw, rh, style.background3)
-- draw text
local font = av:get_font()
local lh = font:get_height() + style.padding.y
local y = ry + style.padding.y / 2
for i, s in ipairs(suggestions) do
local color = (i == suggestions_idx) and style.accent or style.text
common.draw_text(font, color, s.text, "left", rx + style.padding.x, y, rw, lh)
if s.info then
color = (i == suggestions_idx) and style.text or style.dim
common.draw_text(style.font, color, s.info, "right", rx, y, rw - style.padding.x, lh)
end
y = y + lh
end
end
-- patch event logic into RootView
local on_text_input = RootView.on_text_input
local update = RootView.update
local draw = RootView.draw
RootView.on_text_input = function(...)
on_text_input(...)
local av = get_active_view()
if av then
-- update partial symbol and suggestions
partial = get_partial_symbol()
if #partial >= 3 then
update_suggestions()
last_line, last_col = av.doc:get_selection()
else
reset_suggestions()
end
-- scroll if rect is out of bounds of view
local _, y, _, h = get_suggestions_rect(av)
local limit = av.position.y + av.size.y
if y + h > limit then
av.scroll.to.y = av.scroll.y + y + h - limit
end
end
end
RootView.update = function(...)
update(...)
local av = get_active_view()
if av then
-- reset suggestions if caret was moved
local line, col = av.doc:get_selection()
if line ~= last_line or col ~= last_col then
reset_suggestions()
end
end
end
RootView.draw = function(...)
draw(...)
local av = get_active_view()
if av then
-- draw suggestions box after everything else
core.root_view:defer_draw(draw_suggestions_box, av)
end
end
local function predicate()
return get_active_view() and #suggestions > 0
end
command.add(predicate, {
["autocomplete:complete"] = function()
local doc = core.active_view.doc
local line, col = doc:get_selection()
local text = suggestions[suggestions_idx].text
doc:insert(line, col, text)
doc:remove(line, col, line, col - #partial)
doc:set_selection(line, col + #text - #partial)
reset_suggestions()
end,
["autocomplete:previous"] = function()
suggestions_idx = math.max(suggestions_idx - 1, 1)
end,
["autocomplete:next"] = function()
suggestions_idx = math.min(suggestions_idx + 1, #suggestions)
end,
["autocomplete:cancel"] = function()
reset_suggestions()
end,
})
keymap.add {
["tab"] = "autocomplete:complete",
["up"] = "autocomplete:previous",
["down"] = "autocomplete:next",
["escape"] = "autocomplete:cancel",
}
return autocomplete

61
vendor/lite/data/plugins/autoreload.lua vendored Normal file
View file

@ -0,0 +1,61 @@
local core = require "core"
local config = require "core.config"
local Doc = require "core.doc"
local times = setmetatable({}, { __mode = "k" })
local function update_time(doc)
local info = system.get_file_info(doc.filename)
times[doc] = info.modified
end
local function reload_doc(doc)
local fp = io.open(doc.filename, "r")
local text = fp:read("*a")
fp:close()
local sel = { doc:get_selection() }
doc:remove(1, 1, math.huge, math.huge)
doc:insert(1, 1, text:gsub("\r", ""):gsub("\n$", ""))
doc:set_selection(table.unpack(sel))
update_time(doc)
doc:clean()
core.log_quiet("Auto-reloaded doc \"%s\"", doc.filename)
end
core.add_thread(function()
while true do
-- check all doc modified times
for _, doc in ipairs(core.docs) do
local info = system.get_file_info(doc.filename or "")
if info and times[doc] ~= info.modified then
reload_doc(doc)
end
coroutine.yield()
end
-- wait for next scan
coroutine.yield(config.project_scan_rate)
end
end)
-- patch `Doc.save|load` to store modified time
local load = Doc.load
local save = Doc.save
Doc.load = function(self, ...)
local res = load(self, ...)
update_time(self)
return res
end
Doc.save = function(self, ...)
local res = save(self, ...)
update_time(self)
return res
end

59
vendor/lite/data/plugins/language_c.lua vendored Normal file
View file

@ -0,0 +1,59 @@
local syntax = require "core.syntax"
syntax.add {
files = { "%.c$", "%.h$", "%.inl$", "%.cpp$", "%.hpp$" },
comment = "//",
patterns = {
{ pattern = "//.-\n", type = "comment" },
{ pattern = { "/%*", "%*/" }, type = "comment" },
{ pattern = { "#", "[^\\]\n" }, type = "comment" },
{ pattern = { '"', '"', '\\' }, type = "string" },
{ pattern = { "'", "'", '\\' }, type = "string" },
{ pattern = "-?0x%x+", type = "number" },
{ pattern = "-?%d+[%d%.eE]*f?", type = "number" },
{ pattern = "-?%.?%d+f?", type = "number" },
{ pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
{ pattern = "[%a_][%w_]*%f[(]", type = "function" },
{ pattern = "[%a_][%w_]*", type = "symbol" },
},
symbols = {
["if"] = "keyword",
["then"] = "keyword",
["else"] = "keyword",
["elseif"] = "keyword",
["do"] = "keyword",
["while"] = "keyword",
["for"] = "keyword",
["break"] = "keyword",
["continue"] = "keyword",
["return"] = "keyword",
["goto"] = "keyword",
["struct"] = "keyword",
["union"] = "keyword",
["typedef"] = "keyword",
["enum"] = "keyword",
["extern"] = "keyword",
["static"] = "keyword",
["volatile"] = "keyword",
["const"] = "keyword",
["inline"] = "keyword",
["switch"] = "keyword",
["case"] = "keyword",
["default"] = "keyword",
["auto"] = "keyword",
["const"] = "keyword",
["void"] = "keyword",
["int"] = "keyword2",
["short"] = "keyword2",
["long"] = "keyword2",
["float"] = "keyword2",
["double"] = "keyword2",
["char"] = "keyword2",
["unsigned"] = "keyword2",
["bool"] = "keyword2",
["true"] = "literal",
["false"] = "literal",
["NULL"] = "literal",
},
}

View file

@ -0,0 +1,23 @@
local syntax = require "core.syntax"
syntax.add {
files = { "%.css$" },
patterns = {
{ pattern = "\\.", type = "normal" },
{ pattern = "//.-\n", type = "comment" },
{ pattern = { "/%*", "%*/" }, type = "comment" },
{ pattern = { '"', '"', '\\' }, type = "string" },
{ pattern = { "'", "'", '\\' }, type = "string" },
{ pattern = "[%a][%w-]*%s*%f[:]", type = "keyword" },
{ pattern = "#%x+", type = "string" },
{ pattern = "-?%d+[%d%.]*p[xt]", type = "number" },
{ pattern = "-?%d+[%d%.]*deg", type = "number" },
{ pattern = "-?%d+[%d%.]*", type = "number" },
{ pattern = "[%a_][%w_]*", type = "symbol" },
{ pattern = "#[%a][%w_-]*", type = "keyword2" },
{ pattern = "@[%a][%w_-]*", type = "keyword2" },
{ pattern = "%.[%a][%w_-]*", type = "keyword2" },
{ pattern = "[{}:]", type = "operator" },
},
symbols = {},
}

View file

@ -0,0 +1,67 @@
local syntax = require "core.syntax"
syntax.add {
files = { "%.js$", "%.json$", "%.cson$" },
comment = "//",
patterns = {
{ pattern = "//.-\n", type = "comment" },
{ pattern = { "/%*", "%*/" }, type = "comment" },
{ pattern = { '"', '"', '\\' }, type = "string" },
{ pattern = { "'", "'", '\\' }, type = "string" },
{ pattern = { "`", "`", '\\' }, type = "string" },
{ pattern = "0x[%da-fA-F]+", type = "number" },
{ pattern = "-?%d+[%d%.eE]*", type = "number" },
{ pattern = "-?%.?%d+", type = "number" },
{ pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
{ pattern = "[%a_][%w_]*%f[(]", type = "function" },
{ pattern = "[%a_][%w_]*", type = "symbol" },
},
symbols = {
["async"] = "keyword",
["await"] = "keyword",
["break"] = "keyword",
["case"] = "keyword",
["catch"] = "keyword",
["class"] = "keyword",
["const"] = "keyword",
["continue"] = "keyword",
["debugger"] = "keyword",
["default"] = "keyword",
["delete"] = "keyword",
["do"] = "keyword",
["else"] = "keyword",
["export"] = "keyword",
["extends"] = "keyword",
["finally"] = "keyword",
["for"] = "keyword",
["function"] = "keyword",
["get"] = "keyword",
["if"] = "keyword",
["import"] = "keyword",
["in"] = "keyword",
["instanceof"] = "keyword",
["let"] = "keyword",
["new"] = "keyword",
["return"] = "keyword",
["set"] = "keyword",
["static"] = "keyword",
["super"] = "keyword",
["switch"] = "keyword",
["throw"] = "keyword",
["try"] = "keyword",
["typeof"] = "keyword",
["var"] = "keyword",
["void"] = "keyword",
["while"] = "keyword",
["with"] = "keyword",
["yield"] = "keyword",
["true"] = "literal",
["false"] = "literal",
["null"] = "literal",
["undefined"] = "literal",
["arguments"] = "keyword2",
["Infinity"] = "keyword2",
["NaN"] = "keyword2",
["this"] = "keyword2",
},
}

View file

@ -0,0 +1,50 @@
local syntax = require "core.syntax"
syntax.add {
files = "%.lua$",
headers = "^#!.*[ /]lua",
comment = "--",
patterns = {
{ pattern = { '"', '"', '\\' }, type = "string" },
{ pattern = { "'", "'", '\\' }, type = "string" },
{ pattern = { "%[%[", "%]%]" }, type = "string" },
{ pattern = { "%-%-%[%[", "%]%]"}, type = "comment" },
{ pattern = "%-%-.-\n", type = "comment" },
{ pattern = "-?0x%x+", type = "number" },
{ pattern = "-?%d+[%d%.eE]*", type = "number" },
{ pattern = "-?%.?%d+", type = "number" },
{ pattern = "<%a+>", type = "keyword2" },
{ pattern = "%.%.%.?", type = "operator" },
{ pattern = "[<>~=]=", type = "operator" },
{ pattern = "[%+%-=/%*%^%%#<>]", type = "operator" },
{ pattern = "[%a_][%w_]*%s*%f[(\"{]", type = "function" },
{ pattern = "[%a_][%w_]*", type = "symbol" },
{ pattern = "::[%a_][%w_]*::", type = "function" },
},
symbols = {
["if"] = "keyword",
["then"] = "keyword",
["else"] = "keyword",
["elseif"] = "keyword",
["end"] = "keyword",
["do"] = "keyword",
["function"] = "keyword",
["repeat"] = "keyword",
["until"] = "keyword",
["while"] = "keyword",
["for"] = "keyword",
["break"] = "keyword",
["return"] = "keyword",
["local"] = "keyword",
["in"] = "keyword",
["not"] = "keyword",
["and"] = "keyword",
["or"] = "keyword",
["goto"] = "keyword",
["self"] = "keyword2",
["true"] = "literal",
["false"] = "literal",
["nil"] = "literal",
},
}

View file

@ -0,0 +1,21 @@
local syntax = require "core.syntax"
syntax.add {
files = { "%.md$", "%.markdown$" },
patterns = {
{ pattern = "\\.", type = "normal" },
{ pattern = { "<!%-%-", "%-%->" }, type = "comment" },
{ pattern = { "```", "```" }, type = "string" },
{ pattern = { "``", "``", "\\" }, type = "string" },
{ pattern = { "`", "`", "\\" }, type = "string" },
{ pattern = { "~~", "~~", "\\" }, type = "keyword2" },
{ pattern = "%-%-%-+", type = "comment" },
{ pattern = "%*%s+", type = "operator" },
{ pattern = { "%*", "[%*\n]", "\\" }, type = "operator" },
{ pattern = { "%_", "[%_\n]", "\\" }, type = "keyword2" },
{ pattern = "#.-\n", type = "keyword" },
{ pattern = "!?%[.-%]%(.-%)", type = "function" },
{ pattern = "https?://%S+", type = "function" },
},
symbols = { },
}

View file

@ -0,0 +1,55 @@
local syntax = require "core.syntax"
syntax.add {
files = "%.py$",
headers = "^#!.*[ /]python",
comment = "#",
patterns = {
{ pattern = { "#", "\n" }, type = "comment" },
{ pattern = { '[ruU]?"', '"', '\\' }, type = "string" },
{ pattern = { "[ruU]?'", "'", '\\' }, type = "string" },
{ pattern = { '"""', '"""' }, type = "string" },
{ pattern = "0x[%da-fA-F]+", type = "number" },
{ pattern = "-?%d+[%d%.eE]*", type = "number" },
{ pattern = "-?%.?%d+", type = "number" },
{ pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator" },
{ pattern = "[%a_][%w_]*%f[(]", type = "function" },
{ pattern = "[%a_][%w_]*", type = "symbol" },
},
symbols = {
["class"] = "keyword",
["finally"] = "keyword",
["is"] = "keyword",
["return"] = "keyword",
["continue"] = "keyword",
["for"] = "keyword",
["lambda"] = "keyword",
["try"] = "keyword",
["def"] = "keyword",
["from"] = "keyword",
["nonlocal"] = "keyword",
["while"] = "keyword",
["and"] = "keyword",
["global"] = "keyword",
["not"] = "keyword",
["with"] = "keyword",
["as"] = "keyword",
["elif"] = "keyword",
["if"] = "keyword",
["or"] = "keyword",
["else"] = "keyword",
["import"] = "keyword",
["pass"] = "keyword",
["break"] = "keyword",
["except"] = "keyword",
["in"] = "keyword",
["del"] = "keyword",
["raise"] = "keyword",
["yield"] = "keyword",
["assert"] = "keyword",
["self"] = "keyword2",
["None"] = "literal",
["True"] = "literal",
["False"] = "literal",
}
}

View file

@ -0,0 +1,21 @@
local syntax = require "core.syntax"
syntax.add {
files = { "%.xml$", "%.html?$" },
headers = "<%?xml",
patterns = {
{ pattern = { "<!%-%-", "%-%->" }, type = "comment" },
{ pattern = { '%f[^>][^<]', '%f[<]' }, type = "normal" },
{ pattern = { '"', '"', '\\' }, type = "string" },
{ pattern = { "'", "'", '\\' }, type = "string" },
{ pattern = "0x[%da-fA-F]+", type = "number" },
{ pattern = "-?%d+[%d%.]*f?", type = "number" },
{ pattern = "-?%.?%d+f?", type = "number" },
{ pattern = "%f[^<]![%a_][%w_]*", type = "keyword2" },
{ pattern = "%f[^<][%a_][%w_]*", type = "function" },
{ pattern = "%f[^<]/[%a_][%w_]*", type = "function" },
{ pattern = "[%a_][%w_]*", type = "keyword" },
{ pattern = "[/<>=]", type = "operator" },
},
symbols = {},
}

69
vendor/lite/data/plugins/macro.lua vendored Normal file
View file

@ -0,0 +1,69 @@
local core = require "core"
local command = require "core.command"
local keymap = require "core.keymap"
local handled_events = {
["keypressed"] = true,
["keyreleased"] = true,
["textinput"] = true,
}
local state = "stopped"
local event_buffer = {}
local modkeys = {}
local on_event = core.on_event
core.on_event = function(type, ...)
local res = on_event(type, ...)
if state == "recording" and handled_events[type] then
table.insert(event_buffer, { type, ... })
end
return res
end
local function clone(t)
local res = {}
for k, v in pairs(t) do res[k] = v end
return res
end
local function predicate()
return state ~= "playing"
end
command.add(predicate, {
["macro:toggle-record"] = function()
if state == "stopped" then
state = "recording"
event_buffer = {}
modkeys = clone(keymap.modkeys)
core.log("Recording macro...")
else
state = "stopped"
core.log("Stopped recording macro (%d events)", #event_buffer)
end
end,
["macro:play"] = function()
state = "playing"
core.log("Playing macro... (%d events)", #event_buffer)
local mk = keymap.modkeys
keymap.modkeys = clone(modkeys)
for _, ev in ipairs(event_buffer) do
on_event(table.unpack(ev))
core.root_view:update()
end
keymap.modkeys = mk
state = "stopped"
end,
})
keymap.add {
["ctrl+shift+;"] = "macro:toggle-record",
["ctrl+;"] = "macro:play",
}

View file

@ -0,0 +1,271 @@
local core = require "core"
local common = require "core.common"
local keymap = require "core.keymap"
local command = require "core.command"
local style = require "core.style"
local View = require "core.view"
local ResultsView = View:extend()
function ResultsView:new(text, fn)
ResultsView.super.new(self)
self.scrollable = true
self.brightness = 0
self:begin_search(text, fn)
end
function ResultsView:get_name()
return "Search Results"
end
local function find_all_matches_in_file(t, filename, fn)
local fp = io.open(filename)
if not fp then return t end
local n = 1
for line in fp:lines() do
local s = fn(line)
if s then
table.insert(t, { file = filename, text = line, line = n, col = s })
core.redraw = true
end
if n % 100 == 0 then coroutine.yield() end
n = n + 1
core.redraw = true
end
fp:close()
end
function ResultsView:begin_search(text, fn)
self.search_args = { text, fn }
self.results = {}
self.last_file_idx = 1
self.query = text
self.searching = true
self.selected_idx = 0
core.add_thread(function()
for i, file in ipairs(core.project_files) do
if file.type == "file" then
find_all_matches_in_file(self.results, file.filename, fn)
end
self.last_file_idx = i
end
self.searching = false
self.brightness = 100
core.redraw = true
end, self.results)
self.scroll.to.y = 0
end
function ResultsView:refresh()
self:begin_search(table.unpack(self.search_args))
end
function ResultsView:on_mouse_moved(mx, my, ...)
ResultsView.super.on_mouse_moved(self, mx, my, ...)
self.selected_idx = 0
for i, item, x,y,w,h in self:each_visible_result() do
if mx >= x and my >= y and mx < x + w and my < y + h then
self.selected_idx = i
break
end
end
end
function ResultsView:on_mouse_pressed(...)
local caught = ResultsView.super.on_mouse_pressed(self, ...)
if not caught then
self:open_selected_result()
end
end
function ResultsView:open_selected_result()
local res = self.results[self.selected_idx]
if not res then
return
end
core.try(function()
local dv = core.root_view:open_doc(core.open_doc(res.file))
core.root_view.root_node:update_layout()
dv.doc:set_selection(res.line, res.col)
dv:scroll_to_line(res.line, false, true)
end)
end
function ResultsView:update()
self:move_towards("brightness", 0, 0.1)
ResultsView.super.update(self)
end
function ResultsView:get_results_yoffset()
return style.font:get_height() + style.padding.y * 3
end
function ResultsView:get_line_height()
return style.padding.y + style.font:get_height()
end
function ResultsView:get_scrollable_size()
return self:get_results_yoffset() + #self.results * self:get_line_height()
end
function ResultsView:get_visible_results_range()
local lh = self:get_line_height()
local oy = self:get_results_yoffset()
local min = math.max(1, math.floor((self.scroll.y - oy) / lh))
return min, min + math.floor(self.size.y / lh) + 1
end
function ResultsView:each_visible_result()
return coroutine.wrap(function()
local lh = self:get_line_height()
local x, y = self:get_content_offset()
local min, max = self:get_visible_results_range()
y = y + self:get_results_yoffset() + lh * (min - 1)
for i = min, max do
local item = self.results[i]
if not item then break end
coroutine.yield(i, item, x, y, self.size.x, lh)
y = y + lh
end
end)
end
function ResultsView:scroll_to_make_selected_visible()
local h = self:get_line_height()
local y = self:get_results_yoffset() + h * (self.selected_idx - 1)
self.scroll.to.y = math.min(self.scroll.to.y, y)
self.scroll.to.y = math.max(self.scroll.to.y, y + h - self.size.y)
end
function ResultsView:draw()
self:draw_background(style.background)
-- status
local ox, oy = self:get_content_offset()
local x, y = ox + style.padding.x, oy + style.padding.y
local per = self.last_file_idx / #core.project_files
local text
if self.searching then
text = string.format("Searching %d%% (%d of %d files, %d matches) for %q...",
per * 100, self.last_file_idx, #core.project_files,
#self.results, self.query)
else
text = string.format("Found %d matches for %q",
#self.results, self.query)
end
local color = common.lerp(style.text, style.accent, self.brightness / 100)
renderer.draw_text(style.font, text, x, y, color)
-- horizontal line
local yoffset = self:get_results_yoffset()
local x = ox + style.padding.x
local w = self.size.x - style.padding.x * 2
local h = style.divider_size
local color = common.lerp(style.dim, style.text, self.brightness / 100)
renderer.draw_rect(x, oy + yoffset - style.padding.y, w, h, color)
if self.searching then
renderer.draw_rect(x, oy + yoffset - style.padding.y, w * per, h, style.text)
end
-- results
local y1, y2 = self.position.y, self.position.y + self.size.y
for i, item, x,y,w,h in self:each_visible_result() do
local color = style.text
if i == self.selected_idx then
color = style.accent
renderer.draw_rect(x, y, w, h, style.line_highlight)
end
x = x + style.padding.x
local text = string.format("%s at line %d (col %d): ", item.file, item.line, item.col)
x = common.draw_text(style.font, style.dim, text, "left", x, y, w, h)
x = common.draw_text(style.code_font, color, item.text, "left", x, y, w, h)
end
self:draw_scrollbar()
end
local function begin_search(text, fn)
if text == "" then
core.error("Expected non-empty string")
return
end
local rv = ResultsView(text, fn)
core.root_view:get_active_node():add_view(rv)
end
command.add(nil, {
["project-search:find"] = function()
core.command_view:enter("Find Text In Project", function(text)
text = text:lower()
begin_search(text, function(line_text)
return line_text:lower():find(text, nil, true)
end)
end)
end,
["project-search:find-pattern"] = function()
core.command_view:enter("Find Pattern In Project", function(text)
begin_search(text, function(line_text) return line_text:find(text) end)
end)
end,
["project-search:fuzzy-find"] = function()
core.command_view:enter("Fuzzy Find Text In Project", function(text)
begin_search(text, function(line_text)
return common.fuzzy_match(line_text, text) and 1
end)
end)
end,
})
command.add(ResultsView, {
["project-search:select-previous"] = function()
local view = core.active_view
view.selected_idx = math.max(view.selected_idx - 1, 1)
view:scroll_to_make_selected_visible()
end,
["project-search:select-next"] = function()
local view = core.active_view
view.selected_idx = math.min(view.selected_idx + 1, #view.results)
view:scroll_to_make_selected_visible()
end,
["project-search:open-selected"] = function()
core.active_view:open_selected_result()
end,
["project-search:refresh"] = function()
core.active_view:refresh()
end,
})
keymap.add {
["f5"] = "project-search:refresh",
["ctrl+shift+f"] = "project-search:find",
["up"] = "project-search:select-previous",
["down"] = "project-search:select-next",
["return"] = "project-search:open-selected",
}

30
vendor/lite/data/plugins/quote.lua vendored Normal file
View file

@ -0,0 +1,30 @@
local core = require "core"
local command = require "core.command"
local keymap = require "core.keymap"
local escapes = {
["\\"] = "\\\\",
["\""] = "\\\"",
["\n"] = "\\n",
["\r"] = "\\r",
["\t"] = "\\t",
["\b"] = "\\b",
}
local function replace(chr)
return escapes[chr] or string.format("\\x%02x", chr:byte())
end
command.add("core.docview", {
["quote:quote"] = function()
core.active_view.doc:replace(function(text)
return '"' .. text:gsub("[\0-\31\\\"]", replace) .. '"'
end)
end,
})
keymap.add {
["ctrl+'"] = "quote:quote",
}

63
vendor/lite/data/plugins/reflow.lua vendored Normal file
View file

@ -0,0 +1,63 @@
local core = require "core"
local config = require "core.config"
local command = require "core.command"
local keymap = require "core.keymap"
local function wordwrap_text(text, limit)
local t = {}
local n = 0
for word in text:gmatch("%S+") do
if n + #word > limit then
table.insert(t, "\n")
n = 0
elseif #t > 0 then
table.insert(t, " ")
end
table.insert(t, word)
n = n + #word + 1
end
return table.concat(t)
end
command.add("core.docview", {
["reflow:reflow"] = function()
local doc = core.active_view.doc
doc:replace(function(text)
local prefix_set = "[^%w\n%[%](){}`'\"]*"
-- get line prefix and trailing whitespace
local prefix1 = text:match("^\n*" .. prefix_set)
local prefix2 = text:match("\n(" .. prefix_set .. ")", #prefix1+1)
local trailing = text:match("%s*$")
if not prefix2 or prefix2 == "" then
prefix2 = prefix1
end
-- strip all line prefixes and trailing whitespace
text = text:sub(#prefix1+1, -#trailing - 1):gsub("\n" .. prefix_set, "\n")
-- split into blocks, wordwrap and join
local line_limit = config.line_limit - #prefix1
local blocks = {}
text = text:gsub("\n\n", "\0")
for block in text:gmatch("%Z+") do
table.insert(blocks, wordwrap_text(block, line_limit))
end
text = table.concat(blocks, "\n\n")
-- add prefix to start of lines
text = prefix1 .. text:gsub("\n", "\n" .. prefix2) .. trailing
return text
end)
end,
})
keymap.add {
["ctrl+shift+q"] = "reflow:reflow"
}

60
vendor/lite/data/plugins/tabularize.lua vendored Normal file
View file

@ -0,0 +1,60 @@
local core = require "core"
local command = require "core.command"
local translate = require "core.doc.translate"
local function gmatch_to_array(text, ptn)
local res = {}
for x in text:gmatch(ptn) do
table.insert(res, x)
end
return res
end
local function tabularize_lines(lines, delim)
local rows = {}
local cols = {}
-- split lines at delimiters and get maximum width of columns
local ptn = "[^" .. delim:sub(1,1):gsub("%W", "%%%1") .. "]+"
for i, line in ipairs(lines) do
rows[i] = gmatch_to_array(line, ptn)
for j, col in ipairs(rows[i]) do
cols[j] = math.max(#col, cols[j] or 0)
end
end
-- pad columns with space
for _, row in ipairs(rows) do
for i = 1, #row - 1 do
row[i] = row[i] .. string.rep(" ", cols[i] - #row[i])
end
end
-- write columns back to lines array
for i, line in ipairs(lines) do
lines[i] = table.concat(rows[i], delim)
end
end
command.add("core.docview", {
["tabularize:tabularize"] = function()
core.command_view:enter("Tabularize On Delimiter", function(delim)
if delim == "" then delim = " " end
local doc = core.active_view.doc
local line1, col1, line2, col2, swap = doc:get_selection(true)
line1, col1 = doc:position_offset(line1, col1, translate.start_of_line)
line2, col2 = doc:position_offset(line2, col2, translate.end_of_line)
doc:set_selection(line1, col1, line2, col2, swap)
doc:replace(function(text)
local lines = gmatch_to_array(text, "[^\n]*\n?")
tabularize_lines(lines, delim)
return table.concat(lines)
end)
end)
end,
})

197
vendor/lite/data/plugins/treeview.lua vendored Normal file
View file

@ -0,0 +1,197 @@
local core = require "core"
local common = require "core.common"
local command = require "core.command"
local config = require "core.config"
local keymap = require "core.keymap"
local style = require "core.style"
local View = require "core.view"
config.treeview_size = 200 * SCALE
local function get_depth(filename)
local n = 0
for sep in filename:gmatch("[\\/]") do
n = n + 1
end
return n
end
local TreeView = View:extend()
function TreeView:new()
TreeView.super.new(self)
self.scrollable = true
self.visible = true
self.init_size = true
self.cache = {}
end
function TreeView:get_cached(item)
local t = self.cache[item.filename]
if not t then
t = {}
t.filename = item.filename
t.abs_filename = system.absolute_path(item.filename)
t.name = t.filename:match("[^\\/]+$")
t.depth = get_depth(t.filename)
t.type = item.type
self.cache[t.filename] = t
end
return t
end
function TreeView:get_name()
return "Project"
end
function TreeView:get_item_height()
return style.font:get_height() + style.padding.y
end
function TreeView:check_cache()
-- invalidate cache's skip values if project_files has changed
if core.project_files ~= self.last_project_files then
for _, v in pairs(self.cache) do
v.skip = nil
end
self.last_project_files = core.project_files
end
end
function TreeView:each_item()
return coroutine.wrap(function()
self:check_cache()
local ox, oy = self:get_content_offset()
local y = oy + style.padding.y
local w = self.size.x
local h = self:get_item_height()
local i = 1
while i <= #core.project_files do
local item = core.project_files[i]
local cached = self:get_cached(item)
coroutine.yield(cached, ox, y, w, h)
y = y + h
i = i + 1
if not cached.expanded then
if cached.skip then
i = cached.skip
else
local depth = cached.depth
while i <= #core.project_files do
local filename = core.project_files[i].filename
if get_depth(filename) <= depth then break end
i = i + 1
end
cached.skip = i
end
end
end
end)
end
function TreeView:on_mouse_moved(px, py)
self.hovered_item = nil
for item, x,y,w,h in self:each_item() do
if px > x and py > y and px <= x + w and py <= y + h then
self.hovered_item = item
break
end
end
end
function TreeView:on_mouse_pressed(button, x, y)
if not self.hovered_item then
return
elseif self.hovered_item.type == "dir" then
self.hovered_item.expanded = not self.hovered_item.expanded
else
core.try(function()
core.root_view:open_doc(core.open_doc(self.hovered_item.filename))
end)
end
end
function TreeView:update()
-- update width
local dest = self.visible and config.treeview_size or 0
if self.init_size then
self.size.x = dest
self.init_size = false
else
self:move_towards(self.size, "x", dest)
end
TreeView.super.update(self)
end
function TreeView:draw()
self:draw_background(style.background2)
local icon_width = style.icon_font:get_width("D")
local spacing = style.font:get_width(" ") * 2
local doc = core.active_view.doc
local active_filename = doc and system.absolute_path(doc.filename or "")
for item, x,y,w,h in self:each_item() do
local color = style.text
-- highlight active_view doc
if item.abs_filename == active_filename then
color = style.accent
end
-- hovered item background
if item == self.hovered_item then
renderer.draw_rect(x, y, w, h, style.line_highlight)
color = style.accent
end
-- icons
x = x + item.depth * style.padding.x + style.padding.x
if item.type == "dir" then
local icon1 = item.expanded and "-" or "+"
local icon2 = item.expanded and "D" or "d"
common.draw_text(style.icon_font, color, icon1, nil, x, y, 0, h)
x = x + style.padding.x
common.draw_text(style.icon_font, color, icon2, nil, x, y, 0, h)
x = x + icon_width
else
x = x + style.padding.x
common.draw_text(style.icon_font, color, "f", nil, x, y, 0, h)
x = x + icon_width
end
-- text
x = x + spacing
x = common.draw_text(style.font, color, item.name, nil, x, y, 0, h)
end
end
-- init
local view = TreeView()
local node = core.root_view:get_active_node()
node:split("left", view, true)
-- register commands and keymap
command.add(nil, {
["treeview:toggle"] = function()
view.visible = not view.visible
end,
})
keymap.add { ["ctrl+\\"] = "treeview:toggle" }

View file

@ -0,0 +1,36 @@
local core = require "core"
local command = require "core.command"
local Doc = require "core.doc"
local function trim_trailing_whitespace(doc)
local cline, ccol = doc:get_selection()
for i = 1, #doc.lines do
local old_text = doc:get_text(i, 1, i, math.huge)
local new_text = old_text:gsub("%s*$", "")
-- don't remove whitespace which would cause the caret to reposition
if cline == i and ccol > #new_text then
new_text = old_text:sub(1, ccol - 1)
end
if old_text ~= new_text then
doc:insert(i, 1, new_text)
doc:remove(i, #new_text + 1, i, math.huge)
end
end
end
command.add("core.docview", {
["trim-whitespace:trim-trailing-whitespace"] = function()
trim_trailing_whitespace(core.active_view.doc)
end,
})
local save = Doc.save
Doc.save = function(self, ...)
trim_trailing_whitespace(self)
save(self, ...)
end

28
vendor/lite/data/user/colors/fall.lua vendored Normal file
View file

@ -0,0 +1,28 @@
local style = require "core.style"
local common = require "core.common"
style.background = { common.color "#343233" }
style.background2 = { common.color "#2c2a2b" }
style.background3 = { common.color "#2c2a2b" }
style.text = { common.color "#c4b398" }
style.caret = { common.color "#61efce" }
style.accent = { common.color "#ffd152" }
style.dim = { common.color "#615d5f" }
style.divider = { common.color "#242223" }
style.selection = { common.color "#454244" }
style.line_number = { common.color "#454244" }
style.line_number2 = { common.color "#615d5f" }
style.line_highlight = { common.color "#383637" }
style.scrollbar = { common.color "#454344" }
style.scrollbar2 = { common.color "#524F50" }
style.syntax["normal"] = { common.color "#efdab9" }
style.syntax["symbol"] = { common.color "#efdab9" }
style.syntax["comment"] = { common.color "#615d5f" }
style.syntax["keyword"] = { common.color "#d36e2d" }
style.syntax["keyword2"] = { common.color "#ef6179" }
style.syntax["number"] = { common.color "#ffd152" }
style.syntax["literal"] = { common.color "#ffd152" }
style.syntax["string"] = { common.color "#ffd152" }
style.syntax["operator"] = { common.color "#efdab9" }
style.syntax["function"] = { common.color "#61efce" }

28
vendor/lite/data/user/colors/summer.lua vendored Normal file
View file

@ -0,0 +1,28 @@
local style = require "core.style"
local common = require "core.common"
style.background = { common.color "#fbfbfb" }
style.background2 = { common.color "#f2f2f2" }
style.background3 = { common.color "#f2f2f2" }
style.text = { common.color "#404040" }
style.caret = { common.color "#fc1785" }
style.accent = { common.color "#fc1785" }
style.dim = { common.color "#b0b0b0" }
style.divider = { common.color "#e8e8e8" }
style.selection = { common.color "#b7dce8" }
style.line_number = { common.color "#d0d0d0" }
style.line_number2 = { common.color "#808080" }
style.line_highlight = { common.color "#f2f2f2" }
style.scrollbar = { common.color "#e0e0e0" }
style.scrollbar2 = { common.color "#c0c0c0" }
style.syntax["normal"] = { common.color "#181818" }
style.syntax["symbol"] = { common.color "#181818" }
style.syntax["comment"] = { common.color "#22a21f" }
style.syntax["keyword"] = { common.color "#fb6620" }
style.syntax["keyword2"] = { common.color "#fc1785" }
style.syntax["number"] = { common.color "#1586d2" }
style.syntax["literal"] = { common.color "#1586d2" }
style.syntax["string"] = { common.color "#1586d2" }
style.syntax["operator"] = { common.color "#fb6620" }
style.syntax["function"] = { common.color "#fc1785" }

13
vendor/lite/data/user/init.lua vendored Normal file
View file

@ -0,0 +1,13 @@
-- put user settings here
-- this module will be loaded after everything else when the application starts
local keymap = require "core.keymap"
local config = require "core.config"
local style = require "core.style"
-- light theme:
-- require "user.colors.summer"
-- key binding:
-- keymap.add { ["ctrl+escape"] = "core:quit" }

146
vendor/lite/doc/usage.md vendored Normal file
View file

@ -0,0 +1,146 @@
# lite
![screenshot](https://user-images.githubusercontent.com/3920290/81471642-6c165880-91ea-11ea-8cd1-fae7ae8f0bc4.png)
## Overview
lite is a lightweight text editor written mostly in Lua — it aims to provide
something practical, pretty, *small* and fast, implemented as simply as
possible; easy to modify and extend, or to use without doing either.
## Getting Started
When lite is started it's typically opened with a *project directory* — this
is the directory where your project's code and other data resides. The project
directory is set once when lite is started and, for the duration of the
session, cannot be changed.
To open lite with a specific project directory the directory name can be passed
as a command-line argument *(`.` can be passed to use the current directory)* or
the directory can be dragged onto either the lite executable or a running
instance of lite.
The main way of opening files in lite is through the `core:find-file` command
— this provides a fuzzy finder over all of the project's files and can be
opened using the **`ctrl+p`** shortcut by default.
Commands can be run using keyboard shortcuts, or by using the `core:find-command`
command bound to **`ctrl+shift+p`** by default. For example, pressing
`ctrl+shift+p` and typing `newdoc` then pressing `return` would open a new
document. The current keyboard shortcut for a command can be seen to the right
of the command name on the command finder, thus to find the shortcut for a command
`ctrl+shift+p` can be pressed and the command name typed.
## User Module
lite can be configured through use of the user module. The user module can be
used for changing options in the config module, adding additional key bindings,
loading custom color themes, modifying the style or changing any other part of
lite to your personal preference.
The user module is loaded by lite when the application starts, after the plugins
have been loaded.
The user module can be modified by running the `core:open-user-module` command
or otherwise directly opening the `data/user/init.lua` file.
## Project Module
The project module is an optional module which is loaded from the current
project's directory when lite is started. Project modules can be useful for
things like adding custom commands for project-specific build systems, or
loading project-specific plugins.
The project module is loaded by lite when the application starts, after both the
plugins and user module have been loaded.
The project module can be edited by running the `core:open-project-module`
command — if the module does not exist for the current project when the
command is run it will be created.
## Commands
Commands in lite are used both through the command finder (`ctrl+shift+p`) and
by lite's keyboard shortcut system. Commands consist of 3 components:
* **Name** — The command name in the form of `namespace:action-name`, for
example: `doc:select-all`
* **Predicate** — A function that returns true if the command can be ran, for
example, for any document commands the predicate checks whether the active
view is a document
* **Function** — The function which performs the command itself
Commands can be added using the `command.add` function provided by the
`core.command` module:
```lua
local core = require "core"
local command = require "core.command"
command.add("core.docview", {
["doc:save"] = function()
core.active_view.doc:save()
core.log("Saved '%s', core.active_view.doc.filename)
end
})
```
Commands can be performed programatically (eg. from another command or by your
user module) by calling the `command.perform` function after requiring the
`command` module:
```lua
local command = require "core.command"
command.perform "core:quit"
```
## Keymap
All keyboard shortcuts in lite are handled by the `core.keymap` module. A key
binding in lite maps a "stroke" (eg. `ctrl+q`) to one or more commands (eg.
`core:quit`). When the shortcut is pressed lite will iterate each command
assigned to that key and run the *predicate function* for that command — if the
predicate passes it stops iterating and runs the command.
An example of where this used is the default binding of the `tab` key:
``` lua
["tab"] = { "command:complete", "doc:indent" },
```
When tab is pressed the `command:complete` command is attempted which will only
succeed if the command-input at the bottom of the window is active. Otherwise
the `doc:indent` command is attempted which will only succeed if we have a
document as our active view.
A new mapping can be added by your user module as follows:
```lua
local keymap = require "core.keymap"
keymap.add { ["ctrl+q"] = "core:quit" }
```
## Plugins
Plugins in lite are normal lua modules and are treated as such — no
complicated plugin manager is provided, and, once a plugin is loaded, it is never
expected be to have to unload itself.
To install a plugin simply drop it in the `data/plugins` directory — installed
plugins will be automatically loaded when lite starts. To uninstall a plugin the
plugin file can be deleted — any plugin (including those included with lite's
default installation) can be deleted to remove its functionality.
If you want to load a plugin only under a certain circumstance (for example,
only on a given project) the plugin can be placed somewhere other than the
`data/plugins` directory so that it is not automatically loaded. The plugin can
then be loaded manually as needed by using the `require` function.
Plugins can be downloaded from the [plugins repository](https://github.com/rxi/lite-plugins).
## Color Themes
Colors themes in lite are lua modules which overwrite the color fields of lite's
`core.style` module. Color themes should be placed in the `data/user/colors`
directory.
A color theme can be set by requiring it in your user module:
```lua
require "user.colors.winter"
```
Color themes can be downloaded from the [color themes repository](https://github.com/rxi/lite-colors).

BIN
vendor/lite/icon.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

1369
vendor/lite/icon.inl vendored Normal file

File diff suppressed because it is too large Load diff

297
vendor/lite/main.lua vendored Normal file
View file

@ -0,0 +1,297 @@
renderer = {}
function renderer.show_debug(show)
-- useful?
end
function renderer.get_size()
return love.graphics.getWidth(), love.graphics.getHeight()
end
function renderer.begin_frame()
-- handled in love.run
end
function renderer.end_frame()
-- handled in love.run
end
function renderer.set_clip_rect(x, y, w, h)
love.graphics.setScissor(x, y, w, h)
end
function renderer.set_litecolor(color)
local r, g, b, a = 255, 255, 255, 255
if color and #color >= 3 then r, g, b = unpack(color, 1, 3) end
if #color >= 4 then a = color[4] end
love.graphics.setColor(r / 255, g / 255, b / 255, a / 255)
end
function renderer.draw_rect(x, y, w, h, color)
renderer.set_litecolor(color)
love.graphics.rectangle("fill", x, y, w, h)
end
function renderer.draw_text(font, text, x, y, color)
renderer.set_litecolor(color)
love.graphics.setFont(font.font)
if pcall(function() love.graphics.print(text, x, y) end) then
return x + font.font:getWidth(text)
else
return x
end
end
renderer.font = {}
function renderer.font.load(filename, size)
local font = love.graphics.newFont(filename, size)
return {
font = font,
set_tab_width = function(self, n)
-- todo? Ignore?
end,
get_width = function(self, text)
return self.font:getWidth(text)
end,
get_height = function(self)
return self.font:getHeight()
end
}
end
system = {}
system.event_queue = {}
function system.enqueue_love_event(ev, a, b, c, d, e, f)
local function button_name(button)
if button == 1 then return 'left' end
if button == 2 then return 'right' end
if button == 3 then return 'middle' end
return '?'
end
local function key_name(key)
if key:sub(1, 2) == "kp" then
return "keypad " .. key:sub(3)
end
if key:sub(2) == "ctrl" or key:sub(2) == "shift" or key:sub(2) == "alt" or key:sub(2) == "gui" then
if key:sub(1, 1) == "l" then return "left " .. key:sub(2) end
return "right " .. key:sub(2)
end
return key
end
local function convert_love_event()
if ev == 'quit' then
return {'quit'}
elseif ev == 'resize' then
return {'resized', a, b}
elseif ev == 'filedropped' then
return {'filedropped', a:getFilename(), love.mouse.getX(), love.mouse.getY()}
elseif ev == 'keypressed' then
return {'keypressed', key_name(a or b)}
elseif ev == 'keyreleased' then
return {'keyreleased', key_name(a or b)}
elseif ev == 'textinput' then
return {'textinput', a}
elseif ev == 'mousepressed' then
return {'mousepressed', button_name(c), a, b, e}
elseif ev == 'mousereleased' then
return {'mousereleased', button_name(c), a, b}
elseif ev == 'mousemoved' then
return {'mousemoved', a, b, c, d}
elseif ev == 'wheelmoved' then
return {'mousewheel', b}
end
end
local liteev = convert_love_event()
if liteev then
table.insert(system.event_queue, liteev)
end
end
function system.poll_event()
local liteev = table.remove(system.event_queue, 1)
if liteev then
return unpack(liteev)
end
end
function system.wait_event(n)
-- no love2d equivalent
return false
end
function system.set_cursor(cursor)
if cursor == nil then cursor = 'arrow' end
if cursor == 'sizeh' then cursor = 'sizewe' end
if cursor == 'sizev' then cursor = 'sizens' end
love.mouse.setCursor(love.mouse.getSystemCursor(cursor))
end
function system.set_window_title(title)
love.window.setTitle(title)
end
function system.set_window_mode(mode)
love.window.setFullscreen(mode == 'fullscreen')
if mode == nil or mode == 'normal' then love.window.restore() end
if mode == 'maximized' then love.window.maximize() end
end
function system.window_has_focus()
return love.window.hasFocus()
end
function system.show_confirm_dialog(title, msg)
return love.window.showMessageBox(title, msg, { 'Yes', 'No', escapebutton = 2 }, 'warning') == 1
end
function system.chdir(dir)
-- not possible with love2d
end
function system.list_dir(path)
if path == '.' then path = '' end
local info = love.filesystem.getInfo(path)
if info and info.type == 'directory' then
return love.filesystem.getDirectoryItems(path)
elseif info and info.type == 'symlink' then
return love.filesystem.getDirectoryItems(path .. "/.")
end
return nil, "Not a directory"
end
function system.absolute_path(path)
return path -- love.filesystem.getRealDirectory(path)
end
function system.get_file_info(path)
local info = love.filesystem.getInfo(path)
if info then
local type = nil
if info.type == 'file' then
type = 'file'
elseif info.type == 'directory' then
type = 'dir'
elseif info.type == 'symlink' then
if love.filesystem.read(path, 1) then
type = 'file'
else
type = 'dir'
end
end
return {
modified = info.modtime,
size = info.size,
type = type
}
else
return nil, "Doesn't exist"
end
end
function system.get_clipboard()
return love.system.getClipboardText()
end
function system.set_clipboard(text)
love.system.setClipboardText(text)
end
function system.get_time()
return love.timer.getTime()
end
function system.sleep(s)
love.timer.sleep(s)
end
function system.exec(cmd)
-- ehhhh todo I guess
end
function system.fuzzy_match(str, ptn)
local istr = 1
local iptn = 1
local score = 0
local run = 0
while istr <= str:len() and iptn <= ptn:len() do
while str:sub(istr,istr) == ' ' do istr = istr + 1 end
while ptn:sub(iptn,iptn) == ' ' do iptn = iptn + 1 end
local cstr = str:sub(istr,istr)
local cptn = ptn:sub(iptn,iptn)
if cstr:lower() == cptn:lower() then
score = score + (run * 10)
if cstr ~= cptn then score = score - 1 end
run = run + 1
iptn = iptn + 1
else
score = score - 10
run = 0
end
istr = istr + 1
end
if iptn > ptn:len() then
return score - str:len() - istr + 1
end
end
table.unpack = unpack
ARGS = love.arg.parseGameArguments(arg)
VERSION = "1.11"
PLATFORM = "love2d"
SCALE = love.graphics.getDPIScale()
EXEDIR = ""
PATHSEP = package.config:sub(1, 1)
-- love.filesystem.mount(love.filesystem.getSourceBaseDirectory(), love.filesystem.getSourceBaseDirectory())
package.path = love.filesystem.getWorkingDirectory() .. '/data/?.lua;' .. love.filesystem.getWorkingDirectory() .. '/data/?/init.lua;' .. package.path
function love.run()
local core = require('core')
local style = require('core.style')
style.code_font = renderer.font.load(EXEDIR .. "/data/fonts/monospace.ttf", 15 * SCALE)
core.init()
if love.load then love.load(love.arg.parseGameArguments(arg), arg) end
-- We don't want the first frame's dt to include time taken by love.load.
if love.timer then love.timer.step() end
local dt = 0
-- Main loop time.
return function()
-- Process events.
if love.event then
love.event.pump()
for name, a,b,c,d,e,f in love.event.poll() do
system.enqueue_love_event(name, a, b, c, d, e, f)
if name == "quit" then
if not love.quit or not love.quit() then
return a or 0
end
end
love.handlers[name](a,b,c,d,e,f)
end
end
-- Update dt, as we'll be passing it to update
if love.timer then dt = love.timer.step() end
-- Call update and draw
if love.update then love.update(dt) end -- will pass 0 if love.timer is disabled
if love.graphics and love.graphics.isActive() then
love.graphics.origin()
love.graphics.clear(love.graphics.getBackgroundColor())
-- update lite & draw
core.redraw = true
core.frame_start = system.get_time()
core.step()
core.run_threads()
if love.draw then love.draw() end
love.graphics.present()
end
if love.timer then love.timer.sleep(0.001) end
end
end

2
vendor/lite/res.rc vendored Normal file
View file

@ -0,0 +1,2 @@
id ICON "icon.ico"

18
vendor/lite/src/api/api.c vendored Normal file
View file

@ -0,0 +1,18 @@
#include "api.h"
int luaopen_system(lua_State *L);
int luaopen_renderer(lua_State *L);
static const luaL_Reg libs[] = {
{ "system", luaopen_system },
{ "renderer", luaopen_renderer },
{ NULL, NULL }
};
void api_load_libs(lua_State *L) {
for (int i = 0; libs[i].name; i++) {
luaL_requiref(L, libs[i].name, libs[i].func, 1);
}
}

12
vendor/lite/src/api/api.h vendored Normal file
View file

@ -0,0 +1,12 @@
#ifndef API_H
#define API_H
#include "lib/lua52/lua.h"
#include "lib/lua52/lauxlib.h"
#include "lib/lua52/lualib.h"
#define API_TYPE_FONT "Font"
void api_load_libs(lua_State *L);
#endif

106
vendor/lite/src/api/renderer.c vendored Normal file
View file

@ -0,0 +1,106 @@
#include "api.h"
#include "renderer.h"
#include "rencache.h"
static RenColor checkcolor(lua_State *L, int idx, int def) {
RenColor color;
if (lua_isnoneornil(L, idx)) {
return (RenColor) { def, def, def, 255 };
}
lua_rawgeti(L, idx, 1);
lua_rawgeti(L, idx, 2);
lua_rawgeti(L, idx, 3);
lua_rawgeti(L, idx, 4);
color.r = luaL_checknumber(L, -4);
color.g = luaL_checknumber(L, -3);
color.b = luaL_checknumber(L, -2);
color.a = luaL_optnumber(L, -1, 255);
lua_pop(L, 4);
return color;
}
static int f_show_debug(lua_State *L) {
luaL_checkany(L, 1);
rencache_show_debug(lua_toboolean(L, 1));
return 0;
}
static int f_get_size(lua_State *L) {
int w, h;
ren_get_size(&w, &h);
lua_pushnumber(L, w);
lua_pushnumber(L, h);
return 2;
}
static int f_begin_frame(lua_State *L) {
rencache_begin_frame();
return 0;
}
static int f_end_frame(lua_State *L) {
rencache_end_frame();
return 0;
}
static int f_set_clip_rect(lua_State *L) {
RenRect rect;
rect.x = luaL_checknumber(L, 1);
rect.y = luaL_checknumber(L, 2);
rect.width = luaL_checknumber(L, 3);
rect.height = luaL_checknumber(L, 4);
rencache_set_clip_rect(rect);
return 0;
}
static int f_draw_rect(lua_State *L) {
RenRect rect;
rect.x = luaL_checknumber(L, 1);
rect.y = luaL_checknumber(L, 2);
rect.width = luaL_checknumber(L, 3);
rect.height = luaL_checknumber(L, 4);
RenColor color = checkcolor(L, 5, 255);
rencache_draw_rect(rect, color);
return 0;
}
static int f_draw_text(lua_State *L) {
RenFont **font = luaL_checkudata(L, 1, API_TYPE_FONT);
const char *text = luaL_checkstring(L, 2);
int x = luaL_checknumber(L, 3);
int y = luaL_checknumber(L, 4);
RenColor color = checkcolor(L, 5, 255);
x = rencache_draw_text(*font, text, x, y, color);
lua_pushnumber(L, x);
return 1;
}
static const luaL_Reg lib[] = {
{ "show_debug", f_show_debug },
{ "get_size", f_get_size },
{ "begin_frame", f_begin_frame },
{ "end_frame", f_end_frame },
{ "set_clip_rect", f_set_clip_rect },
{ "draw_rect", f_draw_rect },
{ "draw_text", f_draw_text },
{ NULL, NULL }
};
int luaopen_renderer_font(lua_State *L);
int luaopen_renderer(lua_State *L) {
luaL_newlib(L, lib);
luaopen_renderer_font(L);
lua_setfield(L, -2, "font");
return 1;
}

62
vendor/lite/src/api/renderer_font.c vendored Normal file
View file

@ -0,0 +1,62 @@
#include "api.h"
#include "renderer.h"
#include "rencache.h"
static int f_load(lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
float size = luaL_checknumber(L, 2);
RenFont **self = lua_newuserdata(L, sizeof(*self));
luaL_setmetatable(L, API_TYPE_FONT);
*self = ren_load_font(filename, size);
if (!*self) { luaL_error(L, "failed to load font"); }
return 1;
}
static int f_set_tab_width(lua_State *L) {
RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT);
int n = luaL_checknumber(L, 2);
ren_set_font_tab_width(*self, n);
return 0;
}
static int f_gc(lua_State *L) {
RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT);
if (*self) { rencache_free_font(*self); }
return 0;
}
static int f_get_width(lua_State *L) {
RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT);
const char *text = luaL_checkstring(L, 2);
lua_pushnumber(L, ren_get_font_width(*self, text) );
return 1;
}
static int f_get_height(lua_State *L) {
RenFont **self = luaL_checkudata(L, 1, API_TYPE_FONT);
lua_pushnumber(L, ren_get_font_height(*self) );
return 1;
}
static const luaL_Reg lib[] = {
{ "__gc", f_gc },
{ "load", f_load },
{ "set_tab_width", f_set_tab_width },
{ "get_width", f_get_width },
{ "get_height", f_get_height },
{ NULL, NULL }
};
int luaopen_renderer_font(lua_State *L) {
luaL_newmetatable(L, API_TYPE_FONT);
luaL_setfuncs(L, lib, 0);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
return 1;
}

407
vendor/lite/src/api/system.c vendored Normal file
View file

@ -0,0 +1,407 @@
#include <SDL2/SDL.h>
#include <stdbool.h>
#include <ctype.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include "api.h"
#include "rencache.h"
#ifdef _WIN32
#include <windows.h>
#endif
extern SDL_Window *window;
static const char* button_name(int button) {
switch (button) {
case 1 : return "left";
case 2 : return "middle";
case 3 : return "right";
default : return "?";
}
}
static char* key_name(char *dst, int sym) {
strcpy(dst, SDL_GetKeyName(sym));
char *p = dst;
while (*p) {
*p = tolower(*p);
p++;
}
return dst;
}
static int f_poll_event(lua_State *L) {
char buf[16];
int mx, my, wx, wy;
SDL_Event e;
top:
if ( !SDL_PollEvent(&e) ) {
return 0;
}
switch (e.type) {
case SDL_QUIT:
lua_pushstring(L, "quit");
return 1;
case SDL_WINDOWEVENT:
if (e.window.event == SDL_WINDOWEVENT_RESIZED) {
lua_pushstring(L, "resized");
lua_pushnumber(L, e.window.data1);
lua_pushnumber(L, e.window.data2);
return 3;
} else if (e.window.event == SDL_WINDOWEVENT_EXPOSED) {
rencache_invalidate();
lua_pushstring(L, "exposed");
return 1;
}
/* on some systems, when alt-tabbing to the window SDL will queue up
** several KEYDOWN events for the `tab` key; we flush all keydown
** events on focus so these are discarded */
if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED) {
SDL_FlushEvent(SDL_KEYDOWN);
}
goto top;
case SDL_DROPFILE:
SDL_GetGlobalMouseState(&mx, &my);
SDL_GetWindowPosition(window, &wx, &wy);
lua_pushstring(L, "filedropped");
lua_pushstring(L, e.drop.file);
lua_pushnumber(L, mx - wx);
lua_pushnumber(L, my - wy);
SDL_free(e.drop.file);
return 4;
case SDL_KEYDOWN:
lua_pushstring(L, "keypressed");
lua_pushstring(L, key_name(buf, e.key.keysym.sym));
return 2;
case SDL_KEYUP:
lua_pushstring(L, "keyreleased");
lua_pushstring(L, key_name(buf, e.key.keysym.sym));
return 2;
case SDL_TEXTINPUT:
lua_pushstring(L, "textinput");
lua_pushstring(L, e.text.text);
return 2;
case SDL_MOUSEBUTTONDOWN:
if (e.button.button == 1) { SDL_CaptureMouse(1); }
lua_pushstring(L, "mousepressed");
lua_pushstring(L, button_name(e.button.button));
lua_pushnumber(L, e.button.x);
lua_pushnumber(L, e.button.y);
lua_pushnumber(L, e.button.clicks);
return 5;
case SDL_MOUSEBUTTONUP:
if (e.button.button == 1) { SDL_CaptureMouse(0); }
lua_pushstring(L, "mousereleased");
lua_pushstring(L, button_name(e.button.button));
lua_pushnumber(L, e.button.x);
lua_pushnumber(L, e.button.y);
return 4;
case SDL_MOUSEMOTION:
lua_pushstring(L, "mousemoved");
lua_pushnumber(L, e.motion.x);
lua_pushnumber(L, e.motion.y);
lua_pushnumber(L, e.motion.xrel);
lua_pushnumber(L, e.motion.yrel);
return 5;
case SDL_MOUSEWHEEL:
lua_pushstring(L, "mousewheel");
lua_pushnumber(L, e.wheel.y);
return 2;
default:
goto top;
}
return 0;
}
static int f_wait_event(lua_State *L) {
double n = luaL_checknumber(L, 1);
lua_pushboolean(L, SDL_WaitEventTimeout(NULL, n * 1000));
return 1;
}
static SDL_Cursor* cursor_cache[SDL_SYSTEM_CURSOR_HAND + 1];
static const char *cursor_opts[] = {
"arrow",
"ibeam",
"sizeh",
"sizev",
"hand",
NULL
};
static const int cursor_enums[] = {
SDL_SYSTEM_CURSOR_ARROW,
SDL_SYSTEM_CURSOR_IBEAM,
SDL_SYSTEM_CURSOR_SIZEWE,
SDL_SYSTEM_CURSOR_SIZENS,
SDL_SYSTEM_CURSOR_HAND
};
static int f_set_cursor(lua_State *L) {
int opt = luaL_checkoption(L, 1, "arrow", cursor_opts);
int n = cursor_enums[opt];
SDL_Cursor *cursor = cursor_cache[n];
if (!cursor) {
cursor = SDL_CreateSystemCursor(n);
cursor_cache[n] = cursor;
}
SDL_SetCursor(cursor);
return 0;
}
static int f_set_window_title(lua_State *L) {
const char *title = luaL_checkstring(L, 1);
SDL_SetWindowTitle(window, title);
return 0;
}
static const char *window_opts[] = { "normal", "maximized", "fullscreen", 0 };
enum { WIN_NORMAL, WIN_MAXIMIZED, WIN_FULLSCREEN };
static int f_set_window_mode(lua_State *L) {
int n = luaL_checkoption(L, 1, "normal", window_opts);
SDL_SetWindowFullscreen(window,
n == WIN_FULLSCREEN ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
if (n == WIN_NORMAL) { SDL_RestoreWindow(window); }
if (n == WIN_MAXIMIZED) { SDL_MaximizeWindow(window); }
return 0;
}
static int f_window_has_focus(lua_State *L) {
unsigned flags = SDL_GetWindowFlags(window);
lua_pushboolean(L, flags & SDL_WINDOW_INPUT_FOCUS);
return 1;
}
static int f_show_confirm_dialog(lua_State *L) {
const char *title = luaL_checkstring(L, 1);
const char *msg = luaL_checkstring(L, 2);
#if _WIN32
int id = MessageBox(0, msg, title, MB_YESNO | MB_ICONWARNING);
lua_pushboolean(L, id == IDYES);
#else
SDL_MessageBoxButtonData buttons[] = {
{ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "Yes" },
{ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, "No" },
};
SDL_MessageBoxData data = {
.title = title,
.message = msg,
.numbuttons = 2,
.buttons = buttons,
};
int buttonid;
SDL_ShowMessageBox(&data, &buttonid);
lua_pushboolean(L, buttonid == 1);
#endif
return 1;
}
static int f_chdir(lua_State *L) {
const char *path = luaL_checkstring(L, 1);
int err = chdir(path);
if (err) { luaL_error(L, "chdir() failed"); }
return 0;
}
static int f_list_dir(lua_State *L) {
const char *path = luaL_checkstring(L, 1);
DIR *dir = opendir(path);
if (!dir) {
lua_pushnil(L);
lua_pushstring(L, strerror(errno));
return 2;
}
lua_newtable(L);
int i = 1;
struct dirent *entry;
while ( (entry = readdir(dir)) ) {
if (strcmp(entry->d_name, "." ) == 0) { continue; }
if (strcmp(entry->d_name, "..") == 0) { continue; }
lua_pushstring(L, entry->d_name);
lua_rawseti(L, -2, i);
i++;
}
closedir(dir);
return 1;
}
#ifdef _WIN32
#include <windows.h>
#define realpath(x, y) _fullpath(y, x, MAX_PATH)
#endif
static int f_absolute_path(lua_State *L) {
const char *path = luaL_checkstring(L, 1);
char *res = realpath(path, NULL);
if (!res) { return 0; }
lua_pushstring(L, res);
free(res);
return 1;
}
static int f_get_file_info(lua_State *L) {
const char *path = luaL_checkstring(L, 1);
struct stat s;
int err = stat(path, &s);
if (err < 0) {
lua_pushnil(L);
lua_pushstring(L, strerror(errno));
return 2;
}
lua_newtable(L);
lua_pushnumber(L, s.st_mtime);
lua_setfield(L, -2, "modified");
lua_pushnumber(L, s.st_size);
lua_setfield(L, -2, "size");
if (S_ISREG(s.st_mode)) {
lua_pushstring(L, "file");
} else if (S_ISDIR(s.st_mode)) {
lua_pushstring(L, "dir");
} else {
lua_pushnil(L);
}
lua_setfield(L, -2, "type");
return 1;
}
static int f_get_clipboard(lua_State *L) {
char *text = SDL_GetClipboardText();
if (!text) { return 0; }
lua_pushstring(L, text);
SDL_free(text);
return 1;
}
static int f_set_clipboard(lua_State *L) {
const char *text = luaL_checkstring(L, 1);
SDL_SetClipboardText(text);
return 0;
}
static int f_get_time(lua_State *L) {
double n = SDL_GetPerformanceCounter() / (double) SDL_GetPerformanceFrequency();
lua_pushnumber(L, n);
return 1;
}
static int f_sleep(lua_State *L) {
double n = luaL_checknumber(L, 1);
SDL_Delay(n * 1000);
return 0;
}
static int f_exec(lua_State *L) {
size_t len;
const char *cmd = luaL_checklstring(L, 1, &len);
char *buf = malloc(len + 32);
if (!buf) { luaL_error(L, "buffer allocation failed"); }
#if _WIN32
sprintf(buf, "cmd /c \"%s\"", cmd);
WinExec(buf, SW_HIDE);
#else
sprintf(buf, "%s &", cmd);
int res = system(buf);
(void) res;
#endif
free(buf);
return 0;
}
static int f_fuzzy_match(lua_State *L) {
const char *str = luaL_checkstring(L, 1);
const char *ptn = luaL_checkstring(L, 2);
int score = 0;
int run = 0;
while (*str && *ptn) {
while (*str == ' ') { str++; }
while (*ptn == ' ') { ptn++; }
if (tolower(*str) == tolower(*ptn)) {
score += run * 10 - (*str != *ptn);
run++;
ptn++;
} else {
score -= 10;
run = 0;
}
str++;
}
if (*ptn) { return 0; }
lua_pushnumber(L, score - (int) strlen(str));
return 1;
}
static const luaL_Reg lib[] = {
{ "poll_event", f_poll_event },
{ "wait_event", f_wait_event },
{ "set_cursor", f_set_cursor },
{ "set_window_title", f_set_window_title },
{ "set_window_mode", f_set_window_mode },
{ "window_has_focus", f_window_has_focus },
{ "show_confirm_dialog", f_show_confirm_dialog },
{ "chdir", f_chdir },
{ "list_dir", f_list_dir },
{ "absolute_path", f_absolute_path },
{ "get_file_info", f_get_file_info },
{ "get_clipboard", f_get_clipboard },
{ "set_clipboard", f_set_clipboard },
{ "get_time", f_get_time },
{ "sleep", f_sleep },
{ "exec", f_exec },
{ "fuzzy_match", f_fuzzy_match },
{ NULL, NULL }
};
int luaopen_system(lua_State *L) {
luaL_newlib(L, lib);
return 1;
}

1284
vendor/lite/src/lib/lua52/lapi.c vendored Normal file

File diff suppressed because it is too large Load diff

24
vendor/lite/src/lib/lua52/lapi.h vendored Normal file
View file

@ -0,0 +1,24 @@
/*
** $Id: lapi.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
#ifndef lapi_h
#define lapi_h
#include "llimits.h"
#include "lstate.h"
#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
"stack overflow");}
#define adjustresults(L,nres) \
{ if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
"not enough elements in the stack")
#endif

959
vendor/lite/src/lib/lua52/lauxlib.c vendored Normal file
View file

@ -0,0 +1,959 @@
/*
** $Id: lauxlib.c,v 1.248.1.1 2013/04/12 18:48:47 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* This file uses only the official API of Lua.
** Any function declared here could be written as an application function.
*/
#define lauxlib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
/*
** {======================================================
** Traceback
** =======================================================
*/
#define LEVELS1 12 /* size of the first part of the stack */
#define LEVELS2 10 /* size of the second part of the stack */
/*
** search for 'objidx' in table at index -1.
** return 1 + string at top if find a good name.
*/
static int findfield (lua_State *L, int objidx, int level) {
if (level == 0 || !lua_istable(L, -1))
return 0; /* not found */
lua_pushnil(L); /* start 'next' loop */
while (lua_next(L, -2)) { /* for each pair in table */
if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */
if (lua_rawequal(L, objidx, -1)) { /* found object? */
lua_pop(L, 1); /* remove value (but keep name) */
return 1;
}
else if (findfield(L, objidx, level - 1)) { /* try recursively */
lua_remove(L, -2); /* remove table (but keep name) */
lua_pushliteral(L, ".");
lua_insert(L, -2); /* place '.' between the two names */
lua_concat(L, 3);
return 1;
}
}
lua_pop(L, 1); /* remove value */
}
return 0; /* not found */
}
static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
int top = lua_gettop(L);
lua_getinfo(L, "f", ar); /* push function */
lua_pushglobaltable(L);
if (findfield(L, top + 1, 2)) {
lua_copy(L, -1, top + 1); /* move name to proper place */
lua_pop(L, 2); /* remove pushed values */
return 1;
}
else {
lua_settop(L, top); /* remove function and global table */
return 0;
}
}
static void pushfuncname (lua_State *L, lua_Debug *ar) {
if (*ar->namewhat != '\0') /* is there a name? */
lua_pushfstring(L, "function " LUA_QS, ar->name);
else if (*ar->what == 'm') /* main? */
lua_pushliteral(L, "main chunk");
else if (*ar->what == 'C') {
if (pushglobalfuncname(L, ar)) {
lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1));
lua_remove(L, -2); /* remove name */
}
else
lua_pushliteral(L, "?");
}
else
lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined);
}
static int countlevels (lua_State *L) {
lua_Debug ar;
int li = 1, le = 1;
/* find an upper bound */
while (lua_getstack(L, le, &ar)) { li = le; le *= 2; }
/* do a binary search */
while (li < le) {
int m = (li + le)/2;
if (lua_getstack(L, m, &ar)) li = m + 1;
else le = m;
}
return le - 1;
}
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1,
const char *msg, int level) {
lua_Debug ar;
int top = lua_gettop(L);
int numlevels = countlevels(L1);
int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0;
if (msg) lua_pushfstring(L, "%s\n", msg);
lua_pushliteral(L, "stack traceback:");
while (lua_getstack(L1, level++, &ar)) {
if (level == mark) { /* too many levels? */
lua_pushliteral(L, "\n\t..."); /* add a '...' */
level = numlevels - LEVELS2; /* and skip to last ones */
}
else {
lua_getinfo(L1, "Slnt", &ar);
lua_pushfstring(L, "\n\t%s:", ar.short_src);
if (ar.currentline > 0)
lua_pushfstring(L, "%d:", ar.currentline);
lua_pushliteral(L, " in ");
pushfuncname(L, &ar);
if (ar.istailcall)
lua_pushliteral(L, "\n\t(...tail calls...)");
lua_concat(L, lua_gettop(L) - top);
}
}
lua_concat(L, lua_gettop(L) - top);
}
/* }====================================================== */
/*
** {======================================================
** Error-report functions
** =======================================================
*/
LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
lua_Debug ar;
if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);
lua_getinfo(L, "n", &ar);
if (strcmp(ar.namewhat, "method") == 0) {
narg--; /* do not count `self' */
if (narg == 0) /* error is in the self argument itself? */
return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
ar.name, extramsg);
}
if (ar.name == NULL)
ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
narg, ar.name, extramsg);
}
static int typeerror (lua_State *L, int narg, const char *tname) {
const char *msg = lua_pushfstring(L, "%s expected, got %s",
tname, luaL_typename(L, narg));
return luaL_argerror(L, narg, msg);
}
static void tag_error (lua_State *L, int narg, int tag) {
typeerror(L, narg, lua_typename(L, tag));
}
LUALIB_API void luaL_where (lua_State *L, int level) {
lua_Debug ar;
if (lua_getstack(L, level, &ar)) { /* check function at level */
lua_getinfo(L, "Sl", &ar); /* get info about it */
if (ar.currentline > 0) { /* is there info? */
lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline);
return;
}
}
lua_pushliteral(L, ""); /* else, no information available... */
}
LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
luaL_where(L, 1);
lua_pushvfstring(L, fmt, argp);
va_end(argp);
lua_concat(L, 2);
return lua_error(L);
}
LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
int en = errno; /* calls to Lua API may change this value */
if (stat) {
lua_pushboolean(L, 1);
return 1;
}
else {
lua_pushnil(L);
if (fname)
lua_pushfstring(L, "%s: %s", fname, strerror(en));
else
lua_pushstring(L, strerror(en));
lua_pushinteger(L, en);
return 3;
}
}
#if !defined(inspectstat) /* { */
#if defined(LUA_USE_POSIX)
#include <sys/wait.h>
/*
** use appropriate macros to interpret 'pclose' return status
*/
#define inspectstat(stat,what) \
if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \
else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; }
#else
#define inspectstat(stat,what) /* no op */
#endif
#endif /* } */
LUALIB_API int luaL_execresult (lua_State *L, int stat) {
const char *what = "exit"; /* type of termination */
if (stat == -1) /* error? */
return luaL_fileresult(L, 0, NULL);
else {
inspectstat(stat, what); /* interpret result */
if (*what == 'e' && stat == 0) /* successful termination? */
lua_pushboolean(L, 1);
else
lua_pushnil(L);
lua_pushstring(L, what);
lua_pushinteger(L, stat);
return 3; /* return true/nil,what,code */
}
}
/* }====================================================== */
/*
** {======================================================
** Userdata's metatable manipulation
** =======================================================
*/
LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
luaL_getmetatable(L, tname); /* try to get metatable */
if (!lua_isnil(L, -1)) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
lua_pop(L, 1);
lua_newtable(L); /* create metatable */
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
return 1;
}
LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) {
luaL_getmetatable(L, tname);
lua_setmetatable(L, -2);
}
LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
luaL_getmetatable(L, tname); /* get correct metatable */
if (!lua_rawequal(L, -1, -2)) /* not the same? */
p = NULL; /* value is a userdata with wrong metatable */
lua_pop(L, 2); /* remove both metatables */
return p;
}
}
return NULL; /* value is not a userdata with a metatable */
}
LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
void *p = luaL_testudata(L, ud, tname);
if (p == NULL) typeerror(L, ud, tname);
return p;
}
/* }====================================================== */
/*
** {======================================================
** Argument check functions
** =======================================================
*/
LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
const char *const lst[]) {
const char *name = (def) ? luaL_optstring(L, narg, def) :
luaL_checkstring(L, narg);
int i;
for (i=0; lst[i]; i++)
if (strcmp(lst[i], name) == 0)
return i;
return luaL_argerror(L, narg,
lua_pushfstring(L, "invalid option " LUA_QS, name));
}
LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) {
/* keep some extra space to run error routines, if needed */
const int extra = LUA_MINSTACK;
if (!lua_checkstack(L, space + extra)) {
if (msg)
luaL_error(L, "stack overflow (%s)", msg);
else
luaL_error(L, "stack overflow");
}
}
LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
if (lua_type(L, narg) != t)
tag_error(L, narg, t);
}
LUALIB_API void luaL_checkany (lua_State *L, int narg) {
if (lua_type(L, narg) == LUA_TNONE)
luaL_argerror(L, narg, "value expected");
}
LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
const char *s = lua_tolstring(L, narg, len);
if (!s) tag_error(L, narg, LUA_TSTRING);
return s;
}
LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
const char *def, size_t *len) {
if (lua_isnoneornil(L, narg)) {
if (len)
*len = (def ? strlen(def) : 0);
return def;
}
else return luaL_checklstring(L, narg, len);
}
LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
int isnum;
lua_Number d = lua_tonumberx(L, narg, &isnum);
if (!isnum)
tag_error(L, narg, LUA_TNUMBER);
return d;
}
LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
return luaL_opt(L, luaL_checknumber, narg, def);
}
LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
int isnum;
lua_Integer d = lua_tointegerx(L, narg, &isnum);
if (!isnum)
tag_error(L, narg, LUA_TNUMBER);
return d;
}
LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) {
int isnum;
lua_Unsigned d = lua_tounsignedx(L, narg, &isnum);
if (!isnum)
tag_error(L, narg, LUA_TNUMBER);
return d;
}
LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
lua_Integer def) {
return luaL_opt(L, luaL_checkinteger, narg, def);
}
LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg,
lua_Unsigned def) {
return luaL_opt(L, luaL_checkunsigned, narg, def);
}
/* }====================================================== */
/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/
/*
** check whether buffer is using a userdata on the stack as a temporary
** buffer
*/
#define buffonstack(B) ((B)->b != (B)->initb)
/*
** returns a pointer to a free area with at least 'sz' bytes
*/
LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) {
lua_State *L = B->L;
if (B->size - B->n < sz) { /* not enough space? */
char *newbuff;
size_t newsize = B->size * 2; /* double buffer size */
if (newsize - B->n < sz) /* not big enough? */
newsize = B->n + sz;
if (newsize < B->n || newsize - B->n < sz)
luaL_error(L, "buffer too large");
/* create larger buffer */
newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char));
/* move content to new buffer */
memcpy(newbuff, B->b, B->n * sizeof(char));
if (buffonstack(B))
lua_remove(L, -2); /* remove old buffer */
B->b = newbuff;
B->size = newsize;
}
return &B->b[B->n];
}
LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
char *b = luaL_prepbuffsize(B, l);
memcpy(b, s, l * sizeof(char));
luaL_addsize(B, l);
}
LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
luaL_addlstring(B, s, strlen(s));
}
LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
lua_State *L = B->L;
lua_pushlstring(L, B->b, B->n);
if (buffonstack(B))
lua_remove(L, -2); /* remove old buffer */
}
LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) {
luaL_addsize(B, sz);
luaL_pushresult(B);
}
LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
lua_State *L = B->L;
size_t l;
const char *s = lua_tolstring(L, -1, &l);
if (buffonstack(B))
lua_insert(L, -2); /* put value below buffer */
luaL_addlstring(B, s, l);
lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */
}
LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
B->L = L;
B->b = B->initb;
B->n = 0;
B->size = LUAL_BUFFERSIZE;
}
LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) {
luaL_buffinit(L, B);
return luaL_prepbuffsize(B, sz);
}
/* }====================================================== */
/*
** {======================================================
** Reference system
** =======================================================
*/
/* index of free-list header */
#define freelist 0
LUALIB_API int luaL_ref (lua_State *L, int t) {
int ref;
if (lua_isnil(L, -1)) {
lua_pop(L, 1); /* remove from stack */
return LUA_REFNIL; /* `nil' has a unique fixed reference */
}
t = lua_absindex(L, t);
lua_rawgeti(L, t, freelist); /* get first free element */
ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */
lua_pop(L, 1); /* remove it from stack */
if (ref != 0) { /* any free element? */
lua_rawgeti(L, t, ref); /* remove it from list */
lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */
}
else /* no free elements */
ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */
lua_rawseti(L, t, ref);
return ref;
}
LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
if (ref >= 0) {
t = lua_absindex(L, t);
lua_rawgeti(L, t, freelist);
lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */
lua_pushinteger(L, ref);
lua_rawseti(L, t, freelist); /* t[freelist] = ref */
}
}
/* }====================================================== */
/*
** {======================================================
** Load functions
** =======================================================
*/
typedef struct LoadF {
int n; /* number of pre-read characters */
FILE *f; /* file being read */
char buff[LUAL_BUFFERSIZE]; /* area for reading file */
} LoadF;
static const char *getF (lua_State *L, void *ud, size_t *size) {
LoadF *lf = (LoadF *)ud;
(void)L; /* not used */
if (lf->n > 0) { /* are there pre-read characters to be read? */
*size = lf->n; /* return them (chars already in buffer) */
lf->n = 0; /* no more pre-read characters */
}
else { /* read a block from file */
/* 'fread' can return > 0 *and* set the EOF flag. If next call to
'getF' called 'fread', it might still wait for user input.
The next check avoids this problem. */
if (feof(lf->f)) return NULL;
*size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */
}
return lf->buff;
}
static int errfile (lua_State *L, const char *what, int fnameindex) {
const char *serr = strerror(errno);
const char *filename = lua_tostring(L, fnameindex) + 1;
lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
lua_remove(L, fnameindex);
return LUA_ERRFILE;
}
static int skipBOM (LoadF *lf) {
const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */
int c;
lf->n = 0;
do {
c = getc(lf->f);
if (c == EOF || c != *(const unsigned char *)p++) return c;
lf->buff[lf->n++] = c; /* to be read by the parser */
} while (*p != '\0');
lf->n = 0; /* prefix matched; discard it */
return getc(lf->f); /* return next character */
}
/*
** reads the first character of file 'f' and skips an optional BOM mark
** in its beginning plus its first line if it starts with '#'. Returns
** true if it skipped the first line. In any case, '*cp' has the
** first "valid" character of the file (after the optional BOM and
** a first-line comment).
*/
static int skipcomment (LoadF *lf, int *cp) {
int c = *cp = skipBOM(lf);
if (c == '#') { /* first line is a comment (Unix exec. file)? */
do { /* skip first line */
c = getc(lf->f);
} while (c != EOF && c != '\n') ;
*cp = getc(lf->f); /* skip end-of-line, if present */
return 1; /* there was a comment */
}
else return 0; /* no comment */
}
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
const char *mode) {
LoadF lf;
int status, readstatus;
int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
if (filename == NULL) {
lua_pushliteral(L, "=stdin");
lf.f = stdin;
}
else {
lua_pushfstring(L, "@%s", filename);
lf.f = fopen(filename, "r");
if (lf.f == NULL) return errfile(L, "open", fnameindex);
}
if (skipcomment(&lf, &c)) /* read initial portion */
lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
skipcomment(&lf, &c); /* re-read initial portion */
}
if (c != EOF)
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from `lua_load' */
return errfile(L, "read", fnameindex);
}
lua_remove(L, fnameindex);
return status;
}
typedef struct LoadS {
const char *s;
size_t size;
} LoadS;
static const char *getS (lua_State *L, void *ud, size_t *size) {
LoadS *ls = (LoadS *)ud;
(void)L; /* not used */
if (ls->size == 0) return NULL;
*size = ls->size;
ls->size = 0;
return ls->s;
}
LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size,
const char *name, const char *mode) {
LoadS ls;
ls.s = buff;
ls.size = size;
return lua_load(L, getS, &ls, name, mode);
}
LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
return luaL_loadbuffer(L, s, strlen(s), s);
}
/* }====================================================== */
LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
if (!lua_getmetatable(L, obj)) /* no metatable? */
return 0;
lua_pushstring(L, event);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) {
lua_pop(L, 2); /* remove metatable and metafield */
return 0;
}
else {
lua_remove(L, -2); /* remove only metatable */
return 1;
}
}
LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
obj = lua_absindex(L, obj);
if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
return 0;
lua_pushvalue(L, obj);
lua_call(L, 1, 1);
return 1;
}
LUALIB_API int luaL_len (lua_State *L, int idx) {
int l;
int isnum;
lua_len(L, idx);
l = (int)lua_tointegerx(L, -1, &isnum);
if (!isnum)
luaL_error(L, "object length is not a number");
lua_pop(L, 1); /* remove object */
return l;
}
LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */
switch (lua_type(L, idx)) {
case LUA_TNUMBER:
case LUA_TSTRING:
lua_pushvalue(L, idx);
break;
case LUA_TBOOLEAN:
lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false"));
break;
case LUA_TNIL:
lua_pushliteral(L, "nil");
break;
default:
lua_pushfstring(L, "%s: %p", luaL_typename(L, idx),
lua_topointer(L, idx));
break;
}
}
return lua_tolstring(L, -1, len);
}
/*
** {======================================================
** Compatibility with 5.1 module functions
** =======================================================
*/
#if defined(LUA_COMPAT_MODULE)
static const char *luaL_findtable (lua_State *L, int idx,
const char *fname, int szhint) {
const char *e;
if (idx) lua_pushvalue(L, idx);
do {
e = strchr(fname, '.');
if (e == NULL) e = fname + strlen(fname);
lua_pushlstring(L, fname, e - fname);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) { /* no such field? */
lua_pop(L, 1); /* remove this nil */
lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
lua_pushlstring(L, fname, e - fname);
lua_pushvalue(L, -2);
lua_settable(L, -4); /* set new table into field */
}
else if (!lua_istable(L, -1)) { /* field has a non-table value? */
lua_pop(L, 2); /* remove table and value */
return fname; /* return problematic part of the name */
}
lua_remove(L, -2); /* remove previous table */
fname = e + 1;
} while (*e == '.');
return NULL;
}
/*
** Count number of elements in a luaL_Reg list.
*/
static int libsize (const luaL_Reg *l) {
int size = 0;
for (; l && l->name; l++) size++;
return size;
}
/*
** Find or create a module table with a given name. The function
** first looks at the _LOADED table and, if that fails, try a
** global variable with that name. In any case, leaves on the stack
** the module table.
*/
LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
int sizehint) {
luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */
lua_getfield(L, -1, modname); /* get _LOADED[modname] */
if (!lua_istable(L, -1)) { /* not found? */
lua_pop(L, 1); /* remove previous result */
/* try global variable (and create one if it does not exist) */
lua_pushglobaltable(L);
if (luaL_findtable(L, 0, modname, sizehint) != NULL)
luaL_error(L, "name conflict for module " LUA_QS, modname);
lua_pushvalue(L, -1);
lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */
}
lua_remove(L, -2); /* remove _LOADED table */
}
LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
const luaL_Reg *l, int nup) {
luaL_checkversion(L);
if (libname) {
luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */
lua_insert(L, -(nup + 1)); /* move library table to below upvalues */
}
if (l)
luaL_setfuncs(L, l, nup);
else
lua_pop(L, nup); /* remove upvalues */
}
#endif
/* }====================================================== */
/*
** set functions from list 'l' into table at top - 'nup'; each
** function gets the 'nup' elements at the top as upvalues.
** Returns with only the table at the stack.
*/
LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
luaL_checkversion(L);
luaL_checkstack(L, nup, "too many upvalues");
for (; l->name != NULL; l++) { /* fill the table with given functions */
int i;
for (i = 0; i < nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -nup);
lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
lua_setfield(L, -(nup + 2), l->name);
}
lua_pop(L, nup); /* remove upvalues */
}
/*
** ensure that stack[idx][fname] has a table and push that table
** into the stack
*/
LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
lua_getfield(L, idx, fname);
if (lua_istable(L, -1)) return 1; /* table already there */
else {
lua_pop(L, 1); /* remove previous result */
idx = lua_absindex(L, idx);
lua_newtable(L);
lua_pushvalue(L, -1); /* copy to be left at top */
lua_setfield(L, idx, fname); /* assign new table to field */
return 0; /* false, because did not find table there */
}
}
/*
** stripped-down 'require'. Calls 'openf' to open a module,
** registers the result in 'package.loaded' table and, if 'glb'
** is true, also registers the result in the global table.
** Leaves resulting module on the top.
*/
LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
lua_CFunction openf, int glb) {
lua_pushcfunction(L, openf);
lua_pushstring(L, modname); /* argument to open function */
lua_call(L, 1, 1); /* open module */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
lua_pushvalue(L, -2); /* make copy of module (call result) */
lua_setfield(L, -2, modname); /* _LOADED[modname] = module */
lua_pop(L, 1); /* remove _LOADED table */
if (glb) {
lua_pushvalue(L, -1); /* copy of 'mod' */
lua_setglobal(L, modname); /* _G[modname] = module */
}
}
LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
const char *r) {
const char *wild;
size_t l = strlen(p);
luaL_Buffer b;
luaL_buffinit(L, &b);
while ((wild = strstr(s, p)) != NULL) {
luaL_addlstring(&b, s, wild - s); /* push prefix */
luaL_addstring(&b, r); /* push replacement in place of pattern */
s = wild + l; /* continue after `p' */
}
luaL_addstring(&b, s); /* push last suffix */
luaL_pushresult(&b);
return lua_tostring(L, -1);
}
static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
(void)ud; (void)osize; /* not used */
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}
static int panic (lua_State *L) {
luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
return 0; /* return to Lua to abort */
}
LUALIB_API lua_State *luaL_newstate (void) {
lua_State *L = lua_newstate(l_alloc, NULL);
if (L) lua_atpanic(L, &panic);
return L;
}
LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) {
const lua_Number *v = lua_version(L);
if (v != lua_version(NULL))
luaL_error(L, "multiple Lua VMs detected");
else if (*v != ver)
luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
ver, *v);
/* check conversions number -> integer types */
lua_pushnumber(L, -(lua_Number)0x1234);
if (lua_tointeger(L, -1) != -0x1234 ||
lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234)
luaL_error(L, "bad conversion number->int;"
" must recompile Lua with proper settings");
lua_pop(L, 1);
}

212
vendor/lite/src/lib/lua52/lauxlib.h vendored Normal file
View file

@ -0,0 +1,212 @@
/*
** $Id: lauxlib.h,v 1.120.1.1 2013/04/12 18:48:47 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
#ifndef lauxlib_h
#define lauxlib_h
#include <stddef.h>
#include <stdio.h>
#include "lua.h"
/* extra error code for `luaL_load' */
#define LUA_ERRFILE (LUA_ERRERR+1)
typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;
LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver);
#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM)
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
size_t *l);
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
const char *def, size_t *l);
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
lua_Integer def);
LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg);
LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg,
lua_Unsigned def);
LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);
LUALIB_API void (luaL_where) (lua_State *L, int lvl);
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
const char *const lst[]);
LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
/* pre-defined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)
LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
const char *mode);
#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL)
LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
const char *name, const char *mode);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
LUALIB_API lua_State *(luaL_newstate) (void);
LUALIB_API int (luaL_len) (lua_State *L, int idx);
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
const char *r);
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname);
LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
const char *msg, int level);
LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
lua_CFunction openf, int glb);
/*
** ===============================================================
** some useful macros
** ===============================================================
*/
#define luaL_newlibtable(L,l) \
lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
#define luaL_argcheck(L, cond,numarg,extramsg) \
((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))
#define luaL_dofile(L, fn) \
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_dostring(L, s) \
(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))
#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/
typedef struct luaL_Buffer {
char *b; /* buffer address */
size_t size; /* buffer size */
size_t n; /* number of characters in buffer */
lua_State *L;
char initb[LUAL_BUFFERSIZE]; /* initial buffer */
} luaL_Buffer;
#define luaL_addchar(B,c) \
((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \
((B)->b[(B)->n++] = (c)))
#define luaL_addsize(B,s) ((B)->n += (s))
LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz);
LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);
LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
/* }====================================================== */
/*
** {======================================================
** File handles for IO library
** =======================================================
*/
/*
** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
** initial structure 'luaL_Stream' (it may contain other fields
** after that initial structure).
*/
#define LUA_FILEHANDLE "FILE*"
typedef struct luaL_Stream {
FILE *f; /* stream (NULL for incompletely created streams) */
lua_CFunction closef; /* to close stream (NULL for closed streams) */
} luaL_Stream;
/* }====================================================== */
/* compatibility with old module system */
#if defined(LUA_COMPAT_MODULE)
LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
int sizehint);
LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
const luaL_Reg *l, int nup);
#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0))
#endif
#endif

458
vendor/lite/src/lib/lua52/lbaselib.c vendored Normal file
View file

@ -0,0 +1,458 @@
/*
** $Id: lbaselib.c,v 1.276.1.1 2013/04/12 18:48:47 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lbaselib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
static int luaB_print (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
int i;
lua_getglobal(L, "tostring");
for (i=1; i<=n; i++) {
const char *s;
size_t l;
lua_pushvalue(L, -1); /* function to be called */
lua_pushvalue(L, i); /* value to print */
lua_call(L, 1, 1);
s = lua_tolstring(L, -1, &l); /* get result */
if (s == NULL)
return luaL_error(L,
LUA_QL("tostring") " must return a string to " LUA_QL("print"));
if (i>1) luai_writestring("\t", 1);
luai_writestring(s, l);
lua_pop(L, 1); /* pop result */
}
luai_writeline();
return 0;
}
#define SPACECHARS " \f\n\r\t\v"
static int luaB_tonumber (lua_State *L) {
if (lua_isnoneornil(L, 2)) { /* standard conversion */
int isnum;
lua_Number n = lua_tonumberx(L, 1, &isnum);
if (isnum) {
lua_pushnumber(L, n);
return 1;
} /* else not a number; must be something */
luaL_checkany(L, 1);
}
else {
size_t l;
const char *s = luaL_checklstring(L, 1, &l);
const char *e = s + l; /* end point for 's' */
int base = luaL_checkint(L, 2);
int neg = 0;
luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
s += strspn(s, SPACECHARS); /* skip initial spaces */
if (*s == '-') { s++; neg = 1; } /* handle signal */
else if (*s == '+') s++;
if (isalnum((unsigned char)*s)) {
lua_Number n = 0;
do {
int digit = (isdigit((unsigned char)*s)) ? *s - '0'
: toupper((unsigned char)*s) - 'A' + 10;
if (digit >= base) break; /* invalid numeral; force a fail */
n = n * (lua_Number)base + (lua_Number)digit;
s++;
} while (isalnum((unsigned char)*s));
s += strspn(s, SPACECHARS); /* skip trailing spaces */
if (s == e) { /* no invalid trailing characters? */
lua_pushnumber(L, (neg) ? -n : n);
return 1;
} /* else not a number */
} /* else not a number */
}
lua_pushnil(L); /* not a number */
return 1;
}
static int luaB_error (lua_State *L) {
int level = luaL_optint(L, 2, 1);
lua_settop(L, 1);
if (lua_isstring(L, 1) && level > 0) { /* add extra information? */
luaL_where(L, level);
lua_pushvalue(L, 1);
lua_concat(L, 2);
}
return lua_error(L);
}
static int luaB_getmetatable (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_getmetatable(L, 1)) {
lua_pushnil(L);
return 1; /* no metatable */
}
luaL_getmetafield(L, 1, "__metatable");
return 1; /* returns either __metatable field (if present) or metatable */
}
static int luaB_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_checktype(L, 1, LUA_TTABLE);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected");
if (luaL_getmetafield(L, 1, "__metatable"))
return luaL_error(L, "cannot change a protected metatable");
lua_settop(L, 2);
lua_setmetatable(L, 1);
return 1;
}
static int luaB_rawequal (lua_State *L) {
luaL_checkany(L, 1);
luaL_checkany(L, 2);
lua_pushboolean(L, lua_rawequal(L, 1, 2));
return 1;
}
static int luaB_rawlen (lua_State *L) {
int t = lua_type(L, 1);
luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1,
"table or string expected");
lua_pushinteger(L, lua_rawlen(L, 1));
return 1;
}
static int luaB_rawget (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkany(L, 2);
lua_settop(L, 2);
lua_rawget(L, 1);
return 1;
}
static int luaB_rawset (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkany(L, 2);
luaL_checkany(L, 3);
lua_settop(L, 3);
lua_rawset(L, 1);
return 1;
}
static int luaB_collectgarbage (lua_State *L) {
static const char *const opts[] = {"stop", "restart", "collect",
"count", "step", "setpause", "setstepmul",
"setmajorinc", "isrunning", "generational", "incremental", NULL};
static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};
int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
int ex = luaL_optint(L, 2, 0);
int res = lua_gc(L, o, ex);
switch (o) {
case LUA_GCCOUNT: {
int b = lua_gc(L, LUA_GCCOUNTB, 0);
lua_pushnumber(L, res + ((lua_Number)b/1024));
lua_pushinteger(L, b);
return 2;
}
case LUA_GCSTEP: case LUA_GCISRUNNING: {
lua_pushboolean(L, res);
return 1;
}
default: {
lua_pushinteger(L, res);
return 1;
}
}
}
static int luaB_type (lua_State *L) {
luaL_checkany(L, 1);
lua_pushstring(L, luaL_typename(L, 1));
return 1;
}
static int pairsmeta (lua_State *L, const char *method, int iszero,
lua_CFunction iter) {
if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */
luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */
lua_pushcfunction(L, iter); /* will return generator, */
lua_pushvalue(L, 1); /* state, */
if (iszero) lua_pushinteger(L, 0); /* and initial value */
else lua_pushnil(L);
}
else {
lua_pushvalue(L, 1); /* argument 'self' to metamethod */
lua_call(L, 1, 3); /* get 3 values from metamethod */
}
return 3;
}
static int luaB_next (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
if (lua_next(L, 1))
return 2;
else {
lua_pushnil(L);
return 1;
}
}
static int luaB_pairs (lua_State *L) {
return pairsmeta(L, "__pairs", 0, luaB_next);
}
static int ipairsaux (lua_State *L) {
int i = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TTABLE);
i++; /* next value */
lua_pushinteger(L, i);
lua_rawgeti(L, 1, i);
return (lua_isnil(L, -1)) ? 1 : 2;
}
static int luaB_ipairs (lua_State *L) {
return pairsmeta(L, "__ipairs", 1, ipairsaux);
}
static int load_aux (lua_State *L, int status, int envidx) {
if (status == LUA_OK) {
if (envidx != 0) { /* 'env' parameter? */
lua_pushvalue(L, envidx); /* environment for loaded function */
if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */
lua_pop(L, 1); /* remove 'env' if not used by previous call */
}
return 1;
}
else { /* error (message is on top of the stack) */
lua_pushnil(L);
lua_insert(L, -2); /* put before error message */
return 2; /* return nil plus error message */
}
}
static int luaB_loadfile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
const char *mode = luaL_optstring(L, 2, NULL);
int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */
int status = luaL_loadfilex(L, fname, mode);
return load_aux(L, status, env);
}
/*
** {======================================================
** Generic Read function
** =======================================================
*/
/*
** reserved slot, above all arguments, to hold a copy of the returned
** string to avoid it being collected while parsed. 'load' has four
** optional arguments (chunk, source name, mode, and environment).
*/
#define RESERVEDSLOT 5
/*
** Reader for generic `load' function: `lua_load' uses the
** stack for internal stuff, so the reader cannot change the
** stack top. Instead, it keeps its resulting string in a
** reserved slot inside the stack.
*/
static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
(void)(ud); /* not used */
luaL_checkstack(L, 2, "too many nested functions");
lua_pushvalue(L, 1); /* get function */
lua_call(L, 0, 1); /* call it */
if (lua_isnil(L, -1)) {
lua_pop(L, 1); /* pop result */
*size = 0;
return NULL;
}
else if (!lua_isstring(L, -1))
luaL_error(L, "reader function must return a string");
lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */
return lua_tolstring(L, RESERVEDSLOT, size);
}
static int luaB_load (lua_State *L) {
int status;
size_t l;
const char *s = lua_tolstring(L, 1, &l);
const char *mode = luaL_optstring(L, 3, "bt");
int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */
if (s != NULL) { /* loading a string? */
const char *chunkname = luaL_optstring(L, 2, s);
status = luaL_loadbufferx(L, s, l, chunkname, mode);
}
else { /* loading from a reader function */
const char *chunkname = luaL_optstring(L, 2, "=(load)");
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, RESERVEDSLOT); /* create reserved slot */
status = lua_load(L, generic_reader, NULL, chunkname, mode);
}
return load_aux(L, status, env);
}
/* }====================================================== */
static int dofilecont (lua_State *L) {
return lua_gettop(L) - 1;
}
static int luaB_dofile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
lua_settop(L, 1);
if (luaL_loadfile(L, fname) != LUA_OK)
return lua_error(L);
lua_callk(L, 0, LUA_MULTRET, 0, dofilecont);
return dofilecont(L);
}
static int luaB_assert (lua_State *L) {
if (!lua_toboolean(L, 1))
return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
return lua_gettop(L);
}
static int luaB_select (lua_State *L) {
int n = lua_gettop(L);
if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
lua_pushinteger(L, n-1);
return 1;
}
else {
int i = luaL_checkint(L, 1);
if (i < 0) i = n + i;
else if (i > n) i = n;
luaL_argcheck(L, 1 <= i, 1, "index out of range");
return n - i;
}
}
static int finishpcall (lua_State *L, int status) {
if (!lua_checkstack(L, 1)) { /* no space for extra boolean? */
lua_settop(L, 0); /* create space for return values */
lua_pushboolean(L, 0);
lua_pushstring(L, "stack overflow");
return 2; /* return false, msg */
}
lua_pushboolean(L, status); /* first result (status) */
lua_replace(L, 1); /* put first result in first slot */
return lua_gettop(L);
}
static int pcallcont (lua_State *L) {
int status = lua_getctx(L, NULL);
return finishpcall(L, (status == LUA_YIELD));
}
static int luaB_pcall (lua_State *L) {
int status;
luaL_checkany(L, 1);
lua_pushnil(L);
lua_insert(L, 1); /* create space for status result */
status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont);
return finishpcall(L, (status == LUA_OK));
}
static int luaB_xpcall (lua_State *L) {
int status;
int n = lua_gettop(L);
luaL_argcheck(L, n >= 2, 2, "value expected");
lua_pushvalue(L, 1); /* exchange function... */
lua_copy(L, 2, 1); /* ...and error handler */
lua_replace(L, 2);
status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont);
return finishpcall(L, (status == LUA_OK));
}
static int luaB_tostring (lua_State *L) {
luaL_checkany(L, 1);
luaL_tolstring(L, 1, NULL);
return 1;
}
static const luaL_Reg base_funcs[] = {
{"assert", luaB_assert},
{"collectgarbage", luaB_collectgarbage},
{"dofile", luaB_dofile},
{"error", luaB_error},
{"getmetatable", luaB_getmetatable},
{"ipairs", luaB_ipairs},
{"loadfile", luaB_loadfile},
{"load", luaB_load},
#if defined(LUA_COMPAT_LOADSTRING)
{"loadstring", luaB_load},
#endif
{"next", luaB_next},
{"pairs", luaB_pairs},
{"pcall", luaB_pcall},
{"print", luaB_print},
{"rawequal", luaB_rawequal},
{"rawlen", luaB_rawlen},
{"rawget", luaB_rawget},
{"rawset", luaB_rawset},
{"select", luaB_select},
{"setmetatable", luaB_setmetatable},
{"tonumber", luaB_tonumber},
{"tostring", luaB_tostring},
{"type", luaB_type},
{"xpcall", luaB_xpcall},
{NULL, NULL}
};
LUAMOD_API int luaopen_base (lua_State *L) {
/* set global _G */
lua_pushglobaltable(L);
lua_pushglobaltable(L);
lua_setfield(L, -2, "_G");
/* open lib into global table */
luaL_setfuncs(L, base_funcs, 0);
lua_pushliteral(L, LUA_VERSION);
lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */
return 1;
}

212
vendor/lite/src/lib/lua52/lbitlib.c vendored Normal file
View file

@ -0,0 +1,212 @@
/*
** $Id: lbitlib.c,v 1.18.1.2 2013/07/09 18:01:41 roberto Exp $
** Standard library for bitwise operations
** See Copyright Notice in lua.h
*/
#define lbitlib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/* number of bits to consider in a number */
#if !defined(LUA_NBITS)
#define LUA_NBITS 32
#endif
#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
/* macro to trim extra bits */
#define trim(x) ((x) & ALLONES)
/* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */
#define mask(n) (~((ALLONES << 1) << ((n) - 1)))
typedef lua_Unsigned b_uint;
static b_uint andaux (lua_State *L) {
int i, n = lua_gettop(L);
b_uint r = ~(b_uint)0;
for (i = 1; i <= n; i++)
r &= luaL_checkunsigned(L, i);
return trim(r);
}
static int b_and (lua_State *L) {
b_uint r = andaux(L);
lua_pushunsigned(L, r);
return 1;
}
static int b_test (lua_State *L) {
b_uint r = andaux(L);
lua_pushboolean(L, r != 0);
return 1;
}
static int b_or (lua_State *L) {
int i, n = lua_gettop(L);
b_uint r = 0;
for (i = 1; i <= n; i++)
r |= luaL_checkunsigned(L, i);
lua_pushunsigned(L, trim(r));
return 1;
}
static int b_xor (lua_State *L) {
int i, n = lua_gettop(L);
b_uint r = 0;
for (i = 1; i <= n; i++)
r ^= luaL_checkunsigned(L, i);
lua_pushunsigned(L, trim(r));
return 1;
}
static int b_not (lua_State *L) {
b_uint r = ~luaL_checkunsigned(L, 1);
lua_pushunsigned(L, trim(r));
return 1;
}
static int b_shift (lua_State *L, b_uint r, int i) {
if (i < 0) { /* shift right? */
i = -i;
r = trim(r);
if (i >= LUA_NBITS) r = 0;
else r >>= i;
}
else { /* shift left */
if (i >= LUA_NBITS) r = 0;
else r <<= i;
r = trim(r);
}
lua_pushunsigned(L, r);
return 1;
}
static int b_lshift (lua_State *L) {
return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2));
}
static int b_rshift (lua_State *L) {
return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2));
}
static int b_arshift (lua_State *L) {
b_uint r = luaL_checkunsigned(L, 1);
int i = luaL_checkint(L, 2);
if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1))))
return b_shift(L, r, -i);
else { /* arithmetic shift for 'negative' number */
if (i >= LUA_NBITS) r = ALLONES;
else
r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */
lua_pushunsigned(L, r);
return 1;
}
}
static int b_rot (lua_State *L, int i) {
b_uint r = luaL_checkunsigned(L, 1);
i &= (LUA_NBITS - 1); /* i = i % NBITS */
r = trim(r);
if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */
r = (r << i) | (r >> (LUA_NBITS - i));
lua_pushunsigned(L, trim(r));
return 1;
}
static int b_lrot (lua_State *L) {
return b_rot(L, luaL_checkint(L, 2));
}
static int b_rrot (lua_State *L) {
return b_rot(L, -luaL_checkint(L, 2));
}
/*
** get field and width arguments for field-manipulation functions,
** checking whether they are valid.
** ('luaL_error' called without 'return' to avoid later warnings about
** 'width' being used uninitialized.)
*/
static int fieldargs (lua_State *L, int farg, int *width) {
int f = luaL_checkint(L, farg);
int w = luaL_optint(L, farg + 1, 1);
luaL_argcheck(L, 0 <= f, farg, "field cannot be negative");
luaL_argcheck(L, 0 < w, farg + 1, "width must be positive");
if (f + w > LUA_NBITS)
luaL_error(L, "trying to access non-existent bits");
*width = w;
return f;
}
static int b_extract (lua_State *L) {
int w;
b_uint r = luaL_checkunsigned(L, 1);
int f = fieldargs(L, 2, &w);
r = (r >> f) & mask(w);
lua_pushunsigned(L, r);
return 1;
}
static int b_replace (lua_State *L) {
int w;
b_uint r = luaL_checkunsigned(L, 1);
b_uint v = luaL_checkunsigned(L, 2);
int f = fieldargs(L, 3, &w);
int m = mask(w);
v &= m; /* erase bits outside given width */
r = (r & ~(m << f)) | (v << f);
lua_pushunsigned(L, r);
return 1;
}
static const luaL_Reg bitlib[] = {
{"arshift", b_arshift},
{"band", b_and},
{"bnot", b_not},
{"bor", b_or},
{"bxor", b_xor},
{"btest", b_test},
{"extract", b_extract},
{"lrotate", b_lrot},
{"lshift", b_lshift},
{"replace", b_replace},
{"rrotate", b_rrot},
{"rshift", b_rshift},
{NULL, NULL}
};
LUAMOD_API int luaopen_bit32 (lua_State *L) {
luaL_newlib(L, bitlib);
return 1;
}

881
vendor/lite/src/lib/lua52/lcode.c vendored Normal file
View file

@ -0,0 +1,881 @@
/*
** $Id: lcode.c,v 2.62.1.1 2013/04/12 18:48:47 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#define lcode_c
#define LUA_CORE
#include "lua.h"
#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "llex.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstring.h"
#include "ltable.h"
#include "lvm.h"
#define hasjumps(e) ((e)->t != (e)->f)
static int isnumeral(expdesc *e) {
return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
}
void luaK_nil (FuncState *fs, int from, int n) {
Instruction *previous;
int l = from + n - 1; /* last register to set nil */
if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
previous = &fs->f->code[fs->pc-1];
if (GET_OPCODE(*previous) == OP_LOADNIL) {
int pfrom = GETARG_A(*previous);
int pl = pfrom + GETARG_B(*previous);
if ((pfrom <= from && from <= pl + 1) ||
(from <= pfrom && pfrom <= l + 1)) { /* can connect both? */
if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */
if (pl > l) l = pl; /* l = max(l, pl) */
SETARG_A(*previous, from);
SETARG_B(*previous, l - from);
return;
}
} /* else go through */
}
luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */
}
int luaK_jump (FuncState *fs) {
int jpc = fs->jpc; /* save list of jumps to here */
int j;
fs->jpc = NO_JUMP;
j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
luaK_concat(fs, &j, jpc); /* keep them on hold */
return j;
}
void luaK_ret (FuncState *fs, int first, int nret) {
luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
}
static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
luaK_codeABC(fs, op, A, B, C);
return luaK_jump(fs);
}
static void fixjump (FuncState *fs, int pc, int dest) {
Instruction *jmp = &fs->f->code[pc];
int offset = dest-(pc+1);
lua_assert(dest != NO_JUMP);
if (abs(offset) > MAXARG_sBx)
luaX_syntaxerror(fs->ls, "control structure too long");
SETARG_sBx(*jmp, offset);
}
/*
** returns current `pc' and marks it as a jump target (to avoid wrong
** optimizations with consecutive instructions not in the same basic block).
*/
int luaK_getlabel (FuncState *fs) {
fs->lasttarget = fs->pc;
return fs->pc;
}
static int getjump (FuncState *fs, int pc) {
int offset = GETARG_sBx(fs->f->code[pc]);
if (offset == NO_JUMP) /* point to itself represents end of list */
return NO_JUMP; /* end of list */
else
return (pc+1)+offset; /* turn offset into absolute position */
}
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
Instruction *pi = &fs->f->code[pc];
if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
return pi-1;
else
return pi;
}
/*
** check whether list has any jump that do not produce a value
** (or produce an inverted value)
*/
static int need_value (FuncState *fs, int list) {
for (; list != NO_JUMP; list = getjump(fs, list)) {
Instruction i = *getjumpcontrol(fs, list);
if (GET_OPCODE(i) != OP_TESTSET) return 1;
}
return 0; /* not found */
}
static int patchtestreg (FuncState *fs, int node, int reg) {
Instruction *i = getjumpcontrol(fs, node);
if (GET_OPCODE(*i) != OP_TESTSET)
return 0; /* cannot patch other instructions */
if (reg != NO_REG && reg != GETARG_B(*i))
SETARG_A(*i, reg);
else /* no register to put value or register already has the value */
*i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
return 1;
}
static void removevalues (FuncState *fs, int list) {
for (; list != NO_JUMP; list = getjump(fs, list))
patchtestreg(fs, list, NO_REG);
}
static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
int dtarget) {
while (list != NO_JUMP) {
int next = getjump(fs, list);
if (patchtestreg(fs, list, reg))
fixjump(fs, list, vtarget);
else
fixjump(fs, list, dtarget); /* jump to default target */
list = next;
}
}
static void dischargejpc (FuncState *fs) {
patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
fs->jpc = NO_JUMP;
}
void luaK_patchlist (FuncState *fs, int list, int target) {
if (target == fs->pc)
luaK_patchtohere(fs, list);
else {
lua_assert(target < fs->pc);
patchlistaux(fs, list, target, NO_REG, target);
}
}
LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) {
level++; /* argument is +1 to reserve 0 as non-op */
while (list != NO_JUMP) {
int next = getjump(fs, list);
lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
(GETARG_A(fs->f->code[list]) == 0 ||
GETARG_A(fs->f->code[list]) >= level));
SETARG_A(fs->f->code[list], level);
list = next;
}
}
void luaK_patchtohere (FuncState *fs, int list) {
luaK_getlabel(fs);
luaK_concat(fs, &fs->jpc, list);
}
void luaK_concat (FuncState *fs, int *l1, int l2) {
if (l2 == NO_JUMP) return;
else if (*l1 == NO_JUMP)
*l1 = l2;
else {
int list = *l1;
int next;
while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
list = next;
fixjump(fs, list, l2);
}
}
static int luaK_code (FuncState *fs, Instruction i) {
Proto *f = fs->f;
dischargejpc(fs); /* `pc' will change */
/* put new instruction in code array */
luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
MAX_INT, "opcodes");
f->code[fs->pc] = i;
/* save corresponding line information */
luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
MAX_INT, "opcodes");
f->lineinfo[fs->pc] = fs->ls->lastline;
return fs->pc++;
}
int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
lua_assert(getOpMode(o) == iABC);
lua_assert(getBMode(o) != OpArgN || b == 0);
lua_assert(getCMode(o) != OpArgN || c == 0);
lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
return luaK_code(fs, CREATE_ABC(o, a, b, c));
}
int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
lua_assert(getCMode(o) == OpArgN);
lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
return luaK_code(fs, CREATE_ABx(o, a, bc));
}
static int codeextraarg (FuncState *fs, int a) {
lua_assert(a <= MAXARG_Ax);
return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
}
int luaK_codek (FuncState *fs, int reg, int k) {
if (k <= MAXARG_Bx)
return luaK_codeABx(fs, OP_LOADK, reg, k);
else {
int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
codeextraarg(fs, k);
return p;
}
}
void luaK_checkstack (FuncState *fs, int n) {
int newstack = fs->freereg + n;
if (newstack > fs->f->maxstacksize) {
if (newstack >= MAXSTACK)
luaX_syntaxerror(fs->ls, "function or expression too complex");
fs->f->maxstacksize = cast_byte(newstack);
}
}
void luaK_reserveregs (FuncState *fs, int n) {
luaK_checkstack(fs, n);
fs->freereg += n;
}
static void freereg (FuncState *fs, int reg) {
if (!ISK(reg) && reg >= fs->nactvar) {
fs->freereg--;
lua_assert(reg == fs->freereg);
}
}
static void freeexp (FuncState *fs, expdesc *e) {
if (e->k == VNONRELOC)
freereg(fs, e->u.info);
}
static int addk (FuncState *fs, TValue *key, TValue *v) {
lua_State *L = fs->ls->L;
TValue *idx = luaH_set(L, fs->h, key);
Proto *f = fs->f;
int k, oldsize;
if (ttisnumber(idx)) {
lua_Number n = nvalue(idx);
lua_number2int(k, n);
if (luaV_rawequalobj(&f->k[k], v))
return k;
/* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
go through and create a new entry for this value */
}
/* constant not found; create a new entry */
oldsize = f->sizek;
k = fs->nk;
/* numerical value does not need GC barrier;
table has no metatable, so it does not need to invalidate cache */
setnvalue(idx, cast_num(k));
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
setobj(L, &f->k[k], v);
fs->nk++;
luaC_barrier(L, f, v);
return k;
}
int luaK_stringK (FuncState *fs, TString *s) {
TValue o;
setsvalue(fs->ls->L, &o, s);
return addk(fs, &o, &o);
}
int luaK_numberK (FuncState *fs, lua_Number r) {
int n;
lua_State *L = fs->ls->L;
TValue o;
setnvalue(&o, r);
if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */
/* use raw representation as key to avoid numeric problems */
setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
n = addk(fs, L->top - 1, &o);
L->top--;
}
else
n = addk(fs, &o, &o); /* regular case */
return n;
}
static int boolK (FuncState *fs, int b) {
TValue o;
setbvalue(&o, b);
return addk(fs, &o, &o);
}
static int nilK (FuncState *fs) {
TValue k, v;
setnilvalue(&v);
/* cannot use nil as key; instead use table itself to represent nil */
sethvalue(fs->ls->L, &k, fs->h);
return addk(fs, &k, &v);
}
void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
if (e->k == VCALL) { /* expression is an open function call? */
SETARG_C(getcode(fs, e), nresults+1);
}
else if (e->k == VVARARG) {
SETARG_B(getcode(fs, e), nresults+1);
SETARG_A(getcode(fs, e), fs->freereg);
luaK_reserveregs(fs, 1);
}
}
void luaK_setoneret (FuncState *fs, expdesc *e) {
if (e->k == VCALL) { /* expression is an open function call? */
e->k = VNONRELOC;
e->u.info = GETARG_A(getcode(fs, e));
}
else if (e->k == VVARARG) {
SETARG_B(getcode(fs, e), 2);
e->k = VRELOCABLE; /* can relocate its simple result */
}
}
void luaK_dischargevars (FuncState *fs, expdesc *e) {
switch (e->k) {
case VLOCAL: {
e->k = VNONRELOC;
break;
}
case VUPVAL: {
e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
e->k = VRELOCABLE;
break;
}
case VINDEXED: {
OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */
freereg(fs, e->u.ind.idx);
if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */
freereg(fs, e->u.ind.t);
op = OP_GETTABLE;
}
e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
e->k = VRELOCABLE;
break;
}
case VVARARG:
case VCALL: {
luaK_setoneret(fs, e);
break;
}
default: break; /* there is one value available (somewhere) */
}
}
static int code_label (FuncState *fs, int A, int b, int jump) {
luaK_getlabel(fs); /* those instructions may be jump targets */
return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
}
static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
luaK_dischargevars(fs, e);
switch (e->k) {
case VNIL: {
luaK_nil(fs, reg, 1);
break;
}
case VFALSE: case VTRUE: {
luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
break;
}
case VK: {
luaK_codek(fs, reg, e->u.info);
break;
}
case VKNUM: {
luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
break;
}
case VRELOCABLE: {
Instruction *pc = &getcode(fs, e);
SETARG_A(*pc, reg);
break;
}
case VNONRELOC: {
if (reg != e->u.info)
luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
break;
}
default: {
lua_assert(e->k == VVOID || e->k == VJMP);
return; /* nothing to do... */
}
}
e->u.info = reg;
e->k = VNONRELOC;
}
static void discharge2anyreg (FuncState *fs, expdesc *e) {
if (e->k != VNONRELOC) {
luaK_reserveregs(fs, 1);
discharge2reg(fs, e, fs->freereg-1);
}
}
static void exp2reg (FuncState *fs, expdesc *e, int reg) {
discharge2reg(fs, e, reg);
if (e->k == VJMP)
luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */
if (hasjumps(e)) {
int final; /* position after whole expression */
int p_f = NO_JUMP; /* position of an eventual LOAD false */
int p_t = NO_JUMP; /* position of an eventual LOAD true */
if (need_value(fs, e->t) || need_value(fs, e->f)) {
int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
p_f = code_label(fs, reg, 0, 1);
p_t = code_label(fs, reg, 1, 0);
luaK_patchtohere(fs, fj);
}
final = luaK_getlabel(fs);
patchlistaux(fs, e->f, final, reg, p_f);
patchlistaux(fs, e->t, final, reg, p_t);
}
e->f = e->t = NO_JUMP;
e->u.info = reg;
e->k = VNONRELOC;
}
void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
freeexp(fs, e);
luaK_reserveregs(fs, 1);
exp2reg(fs, e, fs->freereg - 1);
}
int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
if (e->k == VNONRELOC) {
if (!hasjumps(e)) return e->u.info; /* exp is already in a register */
if (e->u.info >= fs->nactvar) { /* reg. is not a local? */
exp2reg(fs, e, e->u.info); /* put value on it */
return e->u.info;
}
}
luaK_exp2nextreg(fs, e); /* default */
return e->u.info;
}
void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
if (e->k != VUPVAL || hasjumps(e))
luaK_exp2anyreg(fs, e);
}
void luaK_exp2val (FuncState *fs, expdesc *e) {
if (hasjumps(e))
luaK_exp2anyreg(fs, e);
else
luaK_dischargevars(fs, e);
}
int luaK_exp2RK (FuncState *fs, expdesc *e) {
luaK_exp2val(fs, e);
switch (e->k) {
case VTRUE:
case VFALSE:
case VNIL: {
if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */
e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
e->k = VK;
return RKASK(e->u.info);
}
else break;
}
case VKNUM: {
e->u.info = luaK_numberK(fs, e->u.nval);
e->k = VK;
/* go through */
}
case VK: {
if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */
return RKASK(e->u.info);
else break;
}
default: break;
}
/* not a constant in the right range: put it in a register */
return luaK_exp2anyreg(fs, e);
}
void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
switch (var->k) {
case VLOCAL: {
freeexp(fs, ex);
exp2reg(fs, ex, var->u.info);
return;
}
case VUPVAL: {
int e = luaK_exp2anyreg(fs, ex);
luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
break;
}
case VINDEXED: {
OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
break;
}
default: {
lua_assert(0); /* invalid var kind to store */
break;
}
}
freeexp(fs, ex);
}
void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
int ereg;
luaK_exp2anyreg(fs, e);
ereg = e->u.info; /* register where 'e' was placed */
freeexp(fs, e);
e->u.info = fs->freereg; /* base register for op_self */
e->k = VNONRELOC;
luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */
luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
freeexp(fs, key);
}
static void invertjump (FuncState *fs, expdesc *e) {
Instruction *pc = getjumpcontrol(fs, e->u.info);
lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
GET_OPCODE(*pc) != OP_TEST);
SETARG_A(*pc, !(GETARG_A(*pc)));
}
static int jumponcond (FuncState *fs, expdesc *e, int cond) {
if (e->k == VRELOCABLE) {
Instruction ie = getcode(fs, e);
if (GET_OPCODE(ie) == OP_NOT) {
fs->pc--; /* remove previous OP_NOT */
return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
}
/* else go through */
}
discharge2anyreg(fs, e);
freeexp(fs, e);
return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
}
void luaK_goiftrue (FuncState *fs, expdesc *e) {
int pc; /* pc of last jump */
luaK_dischargevars(fs, e);
switch (e->k) {
case VJMP: {
invertjump(fs, e);
pc = e->u.info;
break;
}
case VK: case VKNUM: case VTRUE: {
pc = NO_JUMP; /* always true; do nothing */
break;
}
default: {
pc = jumponcond(fs, e, 0);
break;
}
}
luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */
luaK_patchtohere(fs, e->t);
e->t = NO_JUMP;
}
void luaK_goiffalse (FuncState *fs, expdesc *e) {
int pc; /* pc of last jump */
luaK_dischargevars(fs, e);
switch (e->k) {
case VJMP: {
pc = e->u.info;
break;
}
case VNIL: case VFALSE: {
pc = NO_JUMP; /* always false; do nothing */
break;
}
default: {
pc = jumponcond(fs, e, 1);
break;
}
}
luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */
luaK_patchtohere(fs, e->f);
e->f = NO_JUMP;
}
static void codenot (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
switch (e->k) {
case VNIL: case VFALSE: {
e->k = VTRUE;
break;
}
case VK: case VKNUM: case VTRUE: {
e->k = VFALSE;
break;
}
case VJMP: {
invertjump(fs, e);
break;
}
case VRELOCABLE:
case VNONRELOC: {
discharge2anyreg(fs, e);
freeexp(fs, e);
e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
e->k = VRELOCABLE;
break;
}
default: {
lua_assert(0); /* cannot happen */
break;
}
}
/* interchange true and false lists */
{ int temp = e->f; e->f = e->t; e->t = temp; }
removevalues(fs, e->f);
removevalues(fs, e->t);
}
void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
lua_assert(!hasjumps(t));
t->u.ind.t = t->u.info;
t->u.ind.idx = luaK_exp2RK(fs, k);
t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
: check_exp(vkisinreg(t->k), VLOCAL);
t->k = VINDEXED;
}
static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
lua_Number r;
if (!isnumeral(e1) || !isnumeral(e2)) return 0;
if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
return 0; /* do not attempt to divide by 0 */
r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
e1->u.nval = r;
return 1;
}
static void codearith (FuncState *fs, OpCode op,
expdesc *e1, expdesc *e2, int line) {
if (constfolding(op, e1, e2))
return;
else {
int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
int o1 = luaK_exp2RK(fs, e1);
if (o1 > o2) {
freeexp(fs, e1);
freeexp(fs, e2);
}
else {
freeexp(fs, e2);
freeexp(fs, e1);
}
e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
e1->k = VRELOCABLE;
luaK_fixline(fs, line);
}
}
static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
expdesc *e2) {
int o1 = luaK_exp2RK(fs, e1);
int o2 = luaK_exp2RK(fs, e2);
freeexp(fs, e2);
freeexp(fs, e1);
if (cond == 0 && op != OP_EQ) {
int temp; /* exchange args to replace by `<' or `<=' */
temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */
cond = 1;
}
e1->u.info = condjump(fs, op, cond, o1, o2);
e1->k = VJMP;
}
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
expdesc e2;
e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
switch (op) {
case OPR_MINUS: {
if (isnumeral(e)) /* minus constant? */
e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */
else {
luaK_exp2anyreg(fs, e);
codearith(fs, OP_UNM, e, &e2, line);
}
break;
}
case OPR_NOT: codenot(fs, e); break;
case OPR_LEN: {
luaK_exp2anyreg(fs, e); /* cannot operate on constants */
codearith(fs, OP_LEN, e, &e2, line);
break;
}
default: lua_assert(0);
}
}
void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
switch (op) {
case OPR_AND: {
luaK_goiftrue(fs, v);
break;
}
case OPR_OR: {
luaK_goiffalse(fs, v);
break;
}
case OPR_CONCAT: {
luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
break;
}
case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
case OPR_MOD: case OPR_POW: {
if (!isnumeral(v)) luaK_exp2RK(fs, v);
break;
}
default: {
luaK_exp2RK(fs, v);
break;
}
}
}
void luaK_posfix (FuncState *fs, BinOpr op,
expdesc *e1, expdesc *e2, int line) {
switch (op) {
case OPR_AND: {
lua_assert(e1->t == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2);
luaK_concat(fs, &e2->f, e1->f);
*e1 = *e2;
break;
}
case OPR_OR: {
lua_assert(e1->f == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2);
luaK_concat(fs, &e2->t, e1->t);
*e1 = *e2;
break;
}
case OPR_CONCAT: {
luaK_exp2val(fs, e2);
if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
freeexp(fs, e1);
SETARG_B(getcode(fs, e2), e1->u.info);
e1->k = VRELOCABLE; e1->u.info = e2->u.info;
}
else {
luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
codearith(fs, OP_CONCAT, e1, e2, line);
}
break;
}
case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
case OPR_MOD: case OPR_POW: {
codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
break;
}
case OPR_EQ: case OPR_LT: case OPR_LE: {
codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
break;
}
case OPR_NE: case OPR_GT: case OPR_GE: {
codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
break;
}
default: lua_assert(0);
}
}
void luaK_fixline (FuncState *fs, int line) {
fs->f->lineinfo[fs->pc - 1] = line;
}
void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
int b = (tostore == LUA_MULTRET) ? 0 : tostore;
lua_assert(tostore != 0);
if (c <= MAXARG_C)
luaK_codeABC(fs, OP_SETLIST, base, b, c);
else if (c <= MAXARG_Ax) {
luaK_codeABC(fs, OP_SETLIST, base, b, 0);
codeextraarg(fs, c);
}
else
luaX_syntaxerror(fs->ls, "constructor too long");
fs->freereg = base + 1; /* free registers with list values */
}

83
vendor/lite/src/lib/lua52/lcode.h vendored Normal file
View file

@ -0,0 +1,83 @@
/*
** $Id: lcode.h,v 1.58.1.1 2013/04/12 18:48:47 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
#ifndef lcode_h
#define lcode_h
#include "llex.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
/*
** Marks the end of a patch list. It is an invalid value both as an absolute
** address, and as a list link (would link an element to itself).
*/
#define NO_JUMP (-1)
/*
** grep "ORDER OPR" if you change these enums (ORDER OP)
*/
typedef enum BinOpr {
OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
OPR_CONCAT,
OPR_EQ, OPR_LT, OPR_LE,
OPR_NE, OPR_GT, OPR_GE,
OPR_AND, OPR_OR,
OPR_NOBINOPR
} BinOpr;
typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
#define getcode(fs,e) ((fs)->f->code[(e)->u.info])
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)
#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t)
LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k);
LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_jump (FuncState *fs);
LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level);
LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
LUAI_FUNC int luaK_getlabel (FuncState *fs);
LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line);
LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1,
expdesc *v2, int line);
LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
#endif

155
vendor/lite/src/lib/lua52/lcorolib.c vendored Normal file
View file

@ -0,0 +1,155 @@
/*
** $Id: lcorolib.c,v 1.5.1.1 2013/04/12 18:48:47 roberto Exp $
** Coroutine Library
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#define lcorolib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
static int auxresume (lua_State *L, lua_State *co, int narg) {
int status;
if (!lua_checkstack(co, narg)) {
lua_pushliteral(L, "too many arguments to resume");
return -1; /* error flag */
}
if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) {
lua_pushliteral(L, "cannot resume dead coroutine");
return -1; /* error flag */
}
lua_xmove(L, co, narg);
status = lua_resume(co, L, narg);
if (status == LUA_OK || status == LUA_YIELD) {
int nres = lua_gettop(co);
if (!lua_checkstack(L, nres + 1)) {
lua_pop(co, nres); /* remove results anyway */
lua_pushliteral(L, "too many results to resume");
return -1; /* error flag */
}
lua_xmove(co, L, nres); /* move yielded values */
return nres;
}
else {
lua_xmove(co, L, 1); /* move error message */
return -1; /* error flag */
}
}
static int luaB_coresume (lua_State *L) {
lua_State *co = lua_tothread(L, 1);
int r;
luaL_argcheck(L, co, 1, "coroutine expected");
r = auxresume(L, co, lua_gettop(L) - 1);
if (r < 0) {
lua_pushboolean(L, 0);
lua_insert(L, -2);
return 2; /* return false + error message */
}
else {
lua_pushboolean(L, 1);
lua_insert(L, -(r + 1));
return r + 1; /* return true + `resume' returns */
}
}
static int luaB_auxwrap (lua_State *L) {
lua_State *co = lua_tothread(L, lua_upvalueindex(1));
int r = auxresume(L, co, lua_gettop(L));
if (r < 0) {
if (lua_isstring(L, -1)) { /* error object is a string? */
luaL_where(L, 1); /* add extra info */
lua_insert(L, -2);
lua_concat(L, 2);
}
return lua_error(L); /* propagate error */
}
return r;
}
static int luaB_cocreate (lua_State *L) {
lua_State *NL;
luaL_checktype(L, 1, LUA_TFUNCTION);
NL = lua_newthread(L);
lua_pushvalue(L, 1); /* move function to top */
lua_xmove(L, NL, 1); /* move function from L to NL */
return 1;
}
static int luaB_cowrap (lua_State *L) {
luaB_cocreate(L);
lua_pushcclosure(L, luaB_auxwrap, 1);
return 1;
}
static int luaB_yield (lua_State *L) {
return lua_yield(L, lua_gettop(L));
}
static int luaB_costatus (lua_State *L) {
lua_State *co = lua_tothread(L, 1);
luaL_argcheck(L, co, 1, "coroutine expected");
if (L == co) lua_pushliteral(L, "running");
else {
switch (lua_status(co)) {
case LUA_YIELD:
lua_pushliteral(L, "suspended");
break;
case LUA_OK: {
lua_Debug ar;
if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */
lua_pushliteral(L, "normal"); /* it is running */
else if (lua_gettop(co) == 0)
lua_pushliteral(L, "dead");
else
lua_pushliteral(L, "suspended"); /* initial state */
break;
}
default: /* some error occurred */
lua_pushliteral(L, "dead");
break;
}
}
return 1;
}
static int luaB_corunning (lua_State *L) {
int ismain = lua_pushthread(L);
lua_pushboolean(L, ismain);
return 2;
}
static const luaL_Reg co_funcs[] = {
{"create", luaB_cocreate},
{"resume", luaB_coresume},
{"running", luaB_corunning},
{"status", luaB_costatus},
{"wrap", luaB_cowrap},
{"yield", luaB_yield},
{NULL, NULL}
};
LUAMOD_API int luaopen_coroutine (lua_State *L) {
luaL_newlib(L, co_funcs);
return 1;
}

52
vendor/lite/src/lib/lua52/lctype.c vendored Normal file
View file

@ -0,0 +1,52 @@
/*
** $Id: lctype.c,v 1.11.1.1 2013/04/12 18:48:47 roberto Exp $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/
#define lctype_c
#define LUA_CORE
#include "lctype.h"
#if !LUA_USE_CTYPE /* { */
#include <limits.h>
LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
0x00, /* EOZ */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */
0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */
0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05,
0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */
0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
#endif /* } */

95
vendor/lite/src/lib/lua52/lctype.h vendored Normal file
View file

@ -0,0 +1,95 @@
/*
** $Id: lctype.h,v 1.12.1.1 2013/04/12 18:48:47 roberto Exp $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/
#ifndef lctype_h
#define lctype_h
#include "lua.h"
/*
** WARNING: the functions defined here do not necessarily correspond
** to the similar functions in the standard C ctype.h. They are
** optimized for the specific needs of Lua
*/
#if !defined(LUA_USE_CTYPE)
#if 'A' == 65 && '0' == 48
/* ASCII case: can use its own tables; faster and fixed */
#define LUA_USE_CTYPE 0
#else
/* must use standard C ctype */
#define LUA_USE_CTYPE 1
#endif
#endif
#if !LUA_USE_CTYPE /* { */
#include <limits.h>
#include "llimits.h"
#define ALPHABIT 0
#define DIGITBIT 1
#define PRINTBIT 2
#define SPACEBIT 3
#define XDIGITBIT 4
#define MASK(B) (1 << (B))
/*
** add 1 to char to allow index -1 (EOZ)
*/
#define testprop(c,p) (luai_ctype_[(c)+1] & (p))
/*
** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
*/
#define lislalpha(c) testprop(c, MASK(ALPHABIT))
#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
#define lisdigit(c) testprop(c, MASK(DIGITBIT))
#define lisspace(c) testprop(c, MASK(SPACEBIT))
#define lisprint(c) testprop(c, MASK(PRINTBIT))
#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
/*
** this 'ltolower' only works for alphabetic characters
*/
#define ltolower(c) ((c) | ('A' ^ 'a'))
/* two more entries for 0 and -1 (EOZ) */
LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2];
#else /* }{ */
/*
** use standard C ctypes
*/
#include <ctype.h>
#define lislalpha(c) (isalpha(c) || (c) == '_')
#define lislalnum(c) (isalnum(c) || (c) == '_')
#define lisdigit(c) (isdigit(c))
#define lisspace(c) (isspace(c))
#define lisprint(c) (isprint(c))
#define lisxdigit(c) (isxdigit(c))
#define ltolower(c) (tolower(c))
#endif /* } */
#endif

408
vendor/lite/src/lib/lua52/ldblib.c vendored Normal file
View file

@ -0,0 +1,408 @@
/*
** $Id: ldblib.c,v 1.132.1.2 2015/02/19 17:16:55 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ldblib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#define HOOKKEY "_HKEY"
static void checkstack (lua_State *L, lua_State *L1, int n) {
if (L != L1 && !lua_checkstack(L1, n))
luaL_error(L, "stack overflow");
}
static int db_getregistry (lua_State *L) {
lua_pushvalue(L, LUA_REGISTRYINDEX);
return 1;
}
static int db_getmetatable (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_getmetatable(L, 1)) {
lua_pushnil(L); /* no metatable */
}
return 1;
}
static int db_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
"nil or table expected");
lua_settop(L, 2);
lua_setmetatable(L, 1);
return 1; /* return 1st argument */
}
static int db_getuservalue (lua_State *L) {
if (lua_type(L, 1) != LUA_TUSERDATA)
lua_pushnil(L);
else
lua_getuservalue(L, 1);
return 1;
}
static int db_setuservalue (lua_State *L) {
if (lua_type(L, 1) == LUA_TLIGHTUSERDATA)
luaL_argerror(L, 1, "full userdata expected, got light userdata");
luaL_checktype(L, 1, LUA_TUSERDATA);
if (!lua_isnoneornil(L, 2))
luaL_checktype(L, 2, LUA_TTABLE);
lua_settop(L, 2);
lua_setuservalue(L, 1);
return 1;
}
static void settabss (lua_State *L, const char *i, const char *v) {
lua_pushstring(L, v);
lua_setfield(L, -2, i);
}
static void settabsi (lua_State *L, const char *i, int v) {
lua_pushinteger(L, v);
lua_setfield(L, -2, i);
}
static void settabsb (lua_State *L, const char *i, int v) {
lua_pushboolean(L, v);
lua_setfield(L, -2, i);
}
static lua_State *getthread (lua_State *L, int *arg) {
if (lua_isthread(L, 1)) {
*arg = 1;
return lua_tothread(L, 1);
}
else {
*arg = 0;
return L;
}
}
static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
if (L == L1) {
lua_pushvalue(L, -2);
lua_remove(L, -3);
}
else
lua_xmove(L1, L, 1);
lua_setfield(L, -2, fname);
}
static int db_getinfo (lua_State *L) {
lua_Debug ar;
int arg;
lua_State *L1 = getthread(L, &arg);
const char *options = luaL_optstring(L, arg+2, "flnStu");
checkstack(L, L1, 3);
if (lua_isnumber(L, arg+1)) {
if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) {
lua_pushnil(L); /* level out of range */
return 1;
}
}
else if (lua_isfunction(L, arg+1)) {
lua_pushfstring(L, ">%s", options);
options = lua_tostring(L, -1);
lua_pushvalue(L, arg+1);
lua_xmove(L, L1, 1);
}
else
return luaL_argerror(L, arg+1, "function or level expected");
if (!lua_getinfo(L1, options, &ar))
return luaL_argerror(L, arg+2, "invalid option");
lua_createtable(L, 0, 2);
if (strchr(options, 'S')) {
settabss(L, "source", ar.source);
settabss(L, "short_src", ar.short_src);
settabsi(L, "linedefined", ar.linedefined);
settabsi(L, "lastlinedefined", ar.lastlinedefined);
settabss(L, "what", ar.what);
}
if (strchr(options, 'l'))
settabsi(L, "currentline", ar.currentline);
if (strchr(options, 'u')) {
settabsi(L, "nups", ar.nups);
settabsi(L, "nparams", ar.nparams);
settabsb(L, "isvararg", ar.isvararg);
}
if (strchr(options, 'n')) {
settabss(L, "name", ar.name);
settabss(L, "namewhat", ar.namewhat);
}
if (strchr(options, 't'))
settabsb(L, "istailcall", ar.istailcall);
if (strchr(options, 'L'))
treatstackoption(L, L1, "activelines");
if (strchr(options, 'f'))
treatstackoption(L, L1, "func");
return 1; /* return table */
}
static int db_getlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
const char *name;
int nvar = luaL_checkint(L, arg+2); /* local-variable index */
if (lua_isfunction(L, arg + 1)) { /* function argument? */
lua_pushvalue(L, arg + 1); /* push function */
lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */
return 1;
}
else { /* stack-level argument */
if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
checkstack(L, L1, 1);
name = lua_getlocal(L1, &ar, nvar);
if (name) {
lua_xmove(L1, L, 1); /* push local value */
lua_pushstring(L, name); /* push name */
lua_pushvalue(L, -2); /* re-order */
return 2;
}
else {
lua_pushnil(L); /* no name (nor value) */
return 1;
}
}
}
static int db_setlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
luaL_checkany(L, arg+3);
lua_settop(L, arg+3);
checkstack(L, L1, 1);
lua_xmove(L, L1, 1);
lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2)));
return 1;
}
static int auxupvalue (lua_State *L, int get) {
const char *name;
int n = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TFUNCTION);
name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
if (name == NULL) return 0;
lua_pushstring(L, name);
lua_insert(L, -(get+1));
return get + 1;
}
static int db_getupvalue (lua_State *L) {
return auxupvalue(L, 1);
}
static int db_setupvalue (lua_State *L) {
luaL_checkany(L, 3);
return auxupvalue(L, 0);
}
static int checkupval (lua_State *L, int argf, int argnup) {
lua_Debug ar;
int nup = luaL_checkint(L, argnup);
luaL_checktype(L, argf, LUA_TFUNCTION);
lua_pushvalue(L, argf);
lua_getinfo(L, ">u", &ar);
luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index");
return nup;
}
static int db_upvalueid (lua_State *L) {
int n = checkupval(L, 1, 2);
lua_pushlightuserdata(L, lua_upvalueid(L, 1, n));
return 1;
}
static int db_upvaluejoin (lua_State *L) {
int n1 = checkupval(L, 1, 2);
int n2 = checkupval(L, 3, 4);
luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected");
luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected");
lua_upvaluejoin(L, 1, n1, 3, n2);
return 0;
}
#define gethooktable(L) luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)
static void hookf (lua_State *L, lua_Debug *ar) {
static const char *const hooknames[] =
{"call", "return", "line", "count", "tail call"};
gethooktable(L);
lua_pushthread(L);
lua_rawget(L, -2);
if (lua_isfunction(L, -1)) {
lua_pushstring(L, hooknames[(int)ar->event]);
if (ar->currentline >= 0)
lua_pushinteger(L, ar->currentline);
else lua_pushnil(L);
lua_assert(lua_getinfo(L, "lS", ar));
lua_call(L, 2, 0);
}
}
static int makemask (const char *smask, int count) {
int mask = 0;
if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
if (strchr(smask, 'r')) mask |= LUA_MASKRET;
if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
if (count > 0) mask |= LUA_MASKCOUNT;
return mask;
}
static char *unmakemask (int mask, char *smask) {
int i = 0;
if (mask & LUA_MASKCALL) smask[i++] = 'c';
if (mask & LUA_MASKRET) smask[i++] = 'r';
if (mask & LUA_MASKLINE) smask[i++] = 'l';
smask[i] = '\0';
return smask;
}
static int db_sethook (lua_State *L) {
int arg, mask, count;
lua_Hook func;
lua_State *L1 = getthread(L, &arg);
if (lua_isnoneornil(L, arg+1)) {
lua_settop(L, arg+1);
func = NULL; mask = 0; count = 0; /* turn off hooks */
}
else {
const char *smask = luaL_checkstring(L, arg+2);
luaL_checktype(L, arg+1, LUA_TFUNCTION);
count = luaL_optint(L, arg+3, 0);
func = hookf; mask = makemask(smask, count);
}
if (gethooktable(L) == 0) { /* creating hook table? */
lua_pushstring(L, "k");
lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */
lua_pushvalue(L, -1);
lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */
}
checkstack(L, L1, 1);
lua_pushthread(L1); lua_xmove(L1, L, 1);
lua_pushvalue(L, arg+1);
lua_rawset(L, -3); /* set new hook */
lua_sethook(L1, func, mask, count); /* set hooks */
return 0;
}
static int db_gethook (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
char buff[5];
int mask = lua_gethookmask(L1);
lua_Hook hook = lua_gethook(L1);
if (hook != NULL && hook != hookf) /* external hook? */
lua_pushliteral(L, "external hook");
else {
gethooktable(L);
checkstack(L, L1, 1);
lua_pushthread(L1); lua_xmove(L1, L, 1);
lua_rawget(L, -2); /* get hook */
lua_remove(L, -2); /* remove hook table */
}
lua_pushstring(L, unmakemask(mask, buff));
lua_pushinteger(L, lua_gethookcount(L1));
return 3;
}
static int db_debug (lua_State *L) {
for (;;) {
char buffer[250];
luai_writestringerror("%s", "lua_debug> ");
if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
strcmp(buffer, "cont\n") == 0)
return 0;
if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") ||
lua_pcall(L, 0, 0, 0))
luai_writestringerror("%s\n", lua_tostring(L, -1));
lua_settop(L, 0); /* remove eventual returns */
}
}
static int db_traceback (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &arg);
const char *msg = lua_tostring(L, arg + 1);
if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */
lua_pushvalue(L, arg + 1); /* return it untouched */
else {
int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0);
luaL_traceback(L, L1, msg, level);
}
return 1;
}
static const luaL_Reg dblib[] = {
{"debug", db_debug},
{"getuservalue", db_getuservalue},
{"gethook", db_gethook},
{"getinfo", db_getinfo},
{"getlocal", db_getlocal},
{"getregistry", db_getregistry},
{"getmetatable", db_getmetatable},
{"getupvalue", db_getupvalue},
{"upvaluejoin", db_upvaluejoin},
{"upvalueid", db_upvalueid},
{"setuservalue", db_setuservalue},
{"sethook", db_sethook},
{"setlocal", db_setlocal},
{"setmetatable", db_setmetatable},
{"setupvalue", db_setupvalue},
{"traceback", db_traceback},
{NULL, NULL}
};
LUAMOD_API int luaopen_debug (lua_State *L) {
luaL_newlib(L, dblib);
return 1;
}

610
vendor/lite/src/lib/lua52/ldebug.c vendored Normal file
View file

@ -0,0 +1,610 @@
/*
** $Id: ldebug.c,v 2.90.1.4 2015/02/19 17:05:13 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
#include <stdarg.h>
#include <stddef.h>
#include <string.h>
#define ldebug_c
#define LUA_CORE
#include "lua.h"
#include "lapi.h"
#include "lcode.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lvm.h"
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
static int currentpc (CallInfo *ci) {
lua_assert(isLua(ci));
return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
}
static int currentline (CallInfo *ci) {
return getfuncline(ci_func(ci)->p, currentpc(ci));
}
static void swapextra (lua_State *L) {
if (L->status == LUA_YIELD) {
CallInfo *ci = L->ci; /* get function that yielded */
StkId temp = ci->func; /* exchange its 'func' and 'extra' values */
ci->func = restorestack(L, ci->extra);
ci->extra = savestack(L, temp);
}
}
/*
** this function can be called asynchronous (e.g. during a signal)
*/
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
if (func == NULL || mask == 0) { /* turn off hooks? */
mask = 0;
func = NULL;
}
if (isLua(L->ci))
L->oldpc = L->ci->u.l.savedpc;
L->hook = func;
L->basehookcount = count;
resethookcount(L);
L->hookmask = cast_byte(mask);
return 1;
}
LUA_API lua_Hook lua_gethook (lua_State *L) {
return L->hook;
}
LUA_API int lua_gethookmask (lua_State *L) {
return L->hookmask;
}
LUA_API int lua_gethookcount (lua_State *L) {
return L->basehookcount;
}
LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
int status;
CallInfo *ci;
if (level < 0) return 0; /* invalid (negative) level */
lua_lock(L);
for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
level--;
if (level == 0 && ci != &L->base_ci) { /* level found? */
status = 1;
ar->i_ci = ci;
}
else status = 0; /* no such level */
lua_unlock(L);
return status;
}
static const char *upvalname (Proto *p, int uv) {
TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
if (s == NULL) return "?";
else return getstr(s);
}
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
int nparams = clLvalue(ci->func)->p->numparams;
if (n >= ci->u.l.base - ci->func - nparams)
return NULL; /* no such vararg */
else {
*pos = ci->func + nparams + n;
return "(*vararg)"; /* generic name for any vararg */
}
}
static const char *findlocal (lua_State *L, CallInfo *ci, int n,
StkId *pos) {
const char *name = NULL;
StkId base;
if (isLua(ci)) {
if (n < 0) /* access to vararg values? */
return findvararg(ci, -n, pos);
else {
base = ci->u.l.base;
name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
}
}
else
base = ci->func + 1;
if (name == NULL) { /* no 'standard' name? */
StkId limit = (ci == L->ci) ? L->top : ci->next->func;
if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
name = "(*temporary)"; /* generic name for any valid slot */
else
return NULL; /* no name */
}
*pos = base + (n - 1);
return name;
}
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
const char *name;
lua_lock(L);
swapextra(L);
if (ar == NULL) { /* information about non-active function? */
if (!isLfunction(L->top - 1)) /* not a Lua function? */
name = NULL;
else /* consider live variables at function start (parameters) */
name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
}
else { /* active function; get information through 'ar' */
StkId pos = 0; /* to avoid warnings */
name = findlocal(L, ar->i_ci, n, &pos);
if (name) {
setobj2s(L, L->top, pos);
api_incr_top(L);
}
}
swapextra(L);
lua_unlock(L);
return name;
}
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
StkId pos = 0; /* to avoid warnings */
const char *name;
lua_lock(L);
swapextra(L);
name = findlocal(L, ar->i_ci, n, &pos);
if (name)
setobjs2s(L, pos, L->top - 1);
L->top--; /* pop value */
swapextra(L);
lua_unlock(L);
return name;
}
static void funcinfo (lua_Debug *ar, Closure *cl) {
if (noLuaClosure(cl)) {
ar->source = "=[C]";
ar->linedefined = -1;
ar->lastlinedefined = -1;
ar->what = "C";
}
else {
Proto *p = cl->l.p;
ar->source = p->source ? getstr(p->source) : "=?";
ar->linedefined = p->linedefined;
ar->lastlinedefined = p->lastlinedefined;
ar->what = (ar->linedefined == 0) ? "main" : "Lua";
}
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
}
static void collectvalidlines (lua_State *L, Closure *f) {
if (noLuaClosure(f)) {
setnilvalue(L->top);
api_incr_top(L);
}
else {
int i;
TValue v;
int *lineinfo = f->l.p->lineinfo;
Table *t = luaH_new(L); /* new table to store active lines */
sethvalue(L, L->top, t); /* push it on stack */
api_incr_top(L);
setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
}
}
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
Closure *f, CallInfo *ci) {
int status = 1;
for (; *what; what++) {
switch (*what) {
case 'S': {
funcinfo(ar, f);
break;
}
case 'l': {
ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
break;
}
case 'u': {
ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
if (noLuaClosure(f)) {
ar->isvararg = 1;
ar->nparams = 0;
}
else {
ar->isvararg = f->l.p->is_vararg;
ar->nparams = f->l.p->numparams;
}
break;
}
case 't': {
ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
break;
}
case 'n': {
/* calling function is a known Lua function? */
if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
ar->namewhat = getfuncname(L, ci->previous, &ar->name);
else
ar->namewhat = NULL;
if (ar->namewhat == NULL) {
ar->namewhat = ""; /* not found */
ar->name = NULL;
}
break;
}
case 'L':
case 'f': /* handled by lua_getinfo */
break;
default: status = 0; /* invalid option */
}
}
return status;
}
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
int status;
Closure *cl;
CallInfo *ci;
StkId func;
lua_lock(L);
swapextra(L);
if (*what == '>') {
ci = NULL;
func = L->top - 1;
api_check(L, ttisfunction(func), "function expected");
what++; /* skip the '>' */
L->top--; /* pop function */
}
else {
ci = ar->i_ci;
func = ci->func;
lua_assert(ttisfunction(ci->func));
}
cl = ttisclosure(func) ? clvalue(func) : NULL;
status = auxgetinfo(L, what, ar, cl, ci);
if (strchr(what, 'f')) {
setobjs2s(L, L->top, func);
api_incr_top(L);
}
swapextra(L);
if (strchr(what, 'L'))
collectvalidlines(L, cl);
lua_unlock(L);
return status;
}
/*
** {======================================================
** Symbolic Execution
** =======================================================
*/
static const char *getobjname (Proto *p, int lastpc, int reg,
const char **name);
/*
** find a "name" for the RK value 'c'
*/
static void kname (Proto *p, int pc, int c, const char **name) {
if (ISK(c)) { /* is 'c' a constant? */
TValue *kvalue = &p->k[INDEXK(c)];
if (ttisstring(kvalue)) { /* literal constant? */
*name = svalue(kvalue); /* it is its own name */
return;
}
/* else no reasonable name found */
}
else { /* 'c' is a register */
const char *what = getobjname(p, pc, c, name); /* search for 'c' */
if (what && *what == 'c') { /* found a constant name? */
return; /* 'name' already filled */
}
/* else no reasonable name found */
}
*name = "?"; /* no reasonable name found */
}
static int filterpc (int pc, int jmptarget) {
if (pc < jmptarget) /* is code conditional (inside a jump)? */
return -1; /* cannot know who sets that register */
else return pc; /* current position sets that register */
}
/*
** try to find last instruction before 'lastpc' that modified register 'reg'
*/
static int findsetreg (Proto *p, int lastpc, int reg) {
int pc;
int setreg = -1; /* keep last instruction that changed 'reg' */
int jmptarget = 0; /* any code before this address is conditional */
for (pc = 0; pc < lastpc; pc++) {
Instruction i = p->code[pc];
OpCode op = GET_OPCODE(i);
int a = GETARG_A(i);
switch (op) {
case OP_LOADNIL: {
int b = GETARG_B(i);
if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
setreg = filterpc(pc, jmptarget);
break;
}
case OP_TFORCALL: {
if (reg >= a + 2) /* affect all regs above its base */
setreg = filterpc(pc, jmptarget);
break;
}
case OP_CALL:
case OP_TAILCALL: {
if (reg >= a) /* affect all registers above base */
setreg = filterpc(pc, jmptarget);
break;
}
case OP_JMP: {
int b = GETARG_sBx(i);
int dest = pc + 1 + b;
/* jump is forward and do not skip `lastpc'? */
if (pc < dest && dest <= lastpc) {
if (dest > jmptarget)
jmptarget = dest; /* update 'jmptarget' */
}
break;
}
case OP_TEST: {
if (reg == a) /* jumped code can change 'a' */
setreg = filterpc(pc, jmptarget);
break;
}
default:
if (testAMode(op) && reg == a) /* any instruction that set A */
setreg = filterpc(pc, jmptarget);
break;
}
}
return setreg;
}
static const char *getobjname (Proto *p, int lastpc, int reg,
const char **name) {
int pc;
*name = luaF_getlocalname(p, reg + 1, lastpc);
if (*name) /* is a local? */
return "local";
/* else try symbolic execution */
pc = findsetreg(p, lastpc, reg);
if (pc != -1) { /* could find instruction? */
Instruction i = p->code[pc];
OpCode op = GET_OPCODE(i);
switch (op) {
case OP_MOVE: {
int b = GETARG_B(i); /* move from 'b' to 'a' */
if (b < GETARG_A(i))
return getobjname(p, pc, b, name); /* get name for 'b' */
break;
}
case OP_GETTABUP:
case OP_GETTABLE: {
int k = GETARG_C(i); /* key index */
int t = GETARG_B(i); /* table index */
const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
? luaF_getlocalname(p, t + 1, pc)
: upvalname(p, t);
kname(p, pc, k, name);
return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
}
case OP_GETUPVAL: {
*name = upvalname(p, GETARG_B(i));
return "upvalue";
}
case OP_LOADK:
case OP_LOADKX: {
int b = (op == OP_LOADK) ? GETARG_Bx(i)
: GETARG_Ax(p->code[pc + 1]);
if (ttisstring(&p->k[b])) {
*name = svalue(&p->k[b]);
return "constant";
}
break;
}
case OP_SELF: {
int k = GETARG_C(i); /* key index */
kname(p, pc, k, name);
return "method";
}
default: break; /* go through to return NULL */
}
}
return NULL; /* could not find reasonable name */
}
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
TMS tm;
Proto *p = ci_func(ci)->p; /* calling function */
int pc = currentpc(ci); /* calling instruction index */
Instruction i = p->code[pc]; /* calling instruction */
switch (GET_OPCODE(i)) {
case OP_CALL:
case OP_TAILCALL: /* get function name */
return getobjname(p, pc, GETARG_A(i), name);
case OP_TFORCALL: { /* for iterator */
*name = "for iterator";
return "for iterator";
}
/* all other instructions can call only through metamethods */
case OP_SELF:
case OP_GETTABUP:
case OP_GETTABLE: tm = TM_INDEX; break;
case OP_SETTABUP:
case OP_SETTABLE: tm = TM_NEWINDEX; break;
case OP_EQ: tm = TM_EQ; break;
case OP_ADD: tm = TM_ADD; break;
case OP_SUB: tm = TM_SUB; break;
case OP_MUL: tm = TM_MUL; break;
case OP_DIV: tm = TM_DIV; break;
case OP_MOD: tm = TM_MOD; break;
case OP_POW: tm = TM_POW; break;
case OP_UNM: tm = TM_UNM; break;
case OP_LEN: tm = TM_LEN; break;
case OP_LT: tm = TM_LT; break;
case OP_LE: tm = TM_LE; break;
case OP_CONCAT: tm = TM_CONCAT; break;
default:
return NULL; /* else no useful name can be found */
}
*name = getstr(G(L)->tmname[tm]);
return "metamethod";
}
/* }====================================================== */
/*
** only ANSI way to check whether a pointer points to an array
** (used only for error messages, so efficiency is not a big concern)
*/
static int isinstack (CallInfo *ci, const TValue *o) {
StkId p;
for (p = ci->u.l.base; p < ci->top; p++)
if (o == p) return 1;
return 0;
}
static const char *getupvalname (CallInfo *ci, const TValue *o,
const char **name) {
LClosure *c = ci_func(ci);
int i;
for (i = 0; i < c->nupvalues; i++) {
if (c->upvals[i]->v == o) {
*name = upvalname(c->p, i);
return "upvalue";
}
}
return NULL;
}
l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
CallInfo *ci = L->ci;
const char *name = NULL;
const char *t = objtypename(o);
const char *kind = NULL;
if (isLua(ci)) {
kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
if (!kind && isinstack(ci, o)) /* no? try a register */
kind = getobjname(ci_func(ci)->p, currentpc(ci),
cast_int(o - ci->u.l.base), &name);
}
if (kind)
luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
op, kind, name, t);
else
luaG_runerror(L, "attempt to %s a %s value", op, t);
}
l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
lua_assert(!ttisstring(p1) && !ttisnumber(p1));
luaG_typeerror(L, p1, "concatenate");
}
l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
TValue temp;
if (luaV_tonumber(p1, &temp) == NULL)
p2 = p1; /* first operand is wrong */
luaG_typeerror(L, p2, "perform arithmetic on");
}
l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = objtypename(p1);
const char *t2 = objtypename(p2);
if (t1 == t2)
luaG_runerror(L, "attempt to compare two %s values", t1);
else
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
}
static void addinfo (lua_State *L, const char *msg) {
CallInfo *ci = L->ci;
if (isLua(ci)) { /* is Lua code? */
char buff[LUA_IDSIZE]; /* add file:line information */
int line = currentline(ci);
TString *src = ci_func(ci)->p->source;
if (src)
luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
else { /* no source available; use "?" instead */
buff[0] = '?'; buff[1] = '\0';
}
luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
}
}
l_noret luaG_errormsg (lua_State *L) {
if (L->errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L->errfunc);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
setobjs2s(L, L->top, L->top - 1); /* move argument */
setobjs2s(L, L->top - 1, errfunc); /* push function */
L->top++;
luaD_call(L, L->top - 2, 1, 0); /* call it */
}
luaD_throw(L, LUA_ERRRUN);
}
l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
addinfo(L, luaO_pushvfstring(L, fmt, argp));
va_end(argp);
luaG_errormsg(L);
}

34
vendor/lite/src/lib/lua52/ldebug.h vendored Normal file
View file

@ -0,0 +1,34 @@
/*
** $Id: ldebug.h,v 2.7.1.1 2013/04/12 18:48:47 roberto Exp $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
#ifndef ldebug_h
#define ldebug_h
#include "lstate.h"
#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)
#define resethookcount(L) (L->hookcount = L->basehookcount)
/* Active Lua function (given call info) */
#define ci_func(ci) (clLvalue((ci)->func))
LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
const char *opname);
LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2);
LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
#endif

681
vendor/lite/src/lib/lua52/ldo.c vendored Normal file
View file

@ -0,0 +1,681 @@
/*
** $Id: ldo.c,v 2.108.1.3 2013/11/08 18:22:50 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>
#define ldo_c
#define LUA_CORE
#include "lua.h"
#include "lapi.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
#include "lundump.h"
#include "lvm.h"
#include "lzio.h"
/*
** {======================================================
** Error-recovery functions
** =======================================================
*/
/*
** LUAI_THROW/LUAI_TRY define how Lua does exception handling. By
** default, Lua handles errors with exceptions when compiling as
** C++ code, with _longjmp/_setjmp when asked to use them, and with
** longjmp/setjmp otherwise.
*/
#if !defined(LUAI_THROW)
#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP)
/* C++ exceptions */
#define LUAI_THROW(L,c) throw(c)
#define LUAI_TRY(L,c,a) \
try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }
#define luai_jmpbuf int /* dummy variable */
#elif defined(LUA_USE_ULONGJMP)
/* in Unix, try _longjmp/_setjmp (more efficient) */
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#else
/* default handling with long jumps */
#define LUAI_THROW(L,c) longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#endif
#endif
/* chain list of long jump buffers */
struct lua_longjmp {
struct lua_longjmp *previous;
luai_jmpbuf b;
volatile int status; /* error code */
};
static void seterrorobj (lua_State *L, int errcode, StkId oldtop) {
switch (errcode) {
case LUA_ERRMEM: { /* memory error? */
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
break;
}
case LUA_ERRERR: {
setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
break;
}
default: {
setobjs2s(L, oldtop, L->top - 1); /* error message on current top */
break;
}
}
L->top = oldtop + 1;
}
l_noret luaD_throw (lua_State *L, int errcode) {
if (L->errorJmp) { /* thread has an error handler? */
L->errorJmp->status = errcode; /* set status */
LUAI_THROW(L, L->errorJmp); /* jump to it */
}
else { /* thread has no error handler */
L->status = cast_byte(errcode); /* mark it as dead */
if (G(L)->mainthread->errorJmp) { /* main thread has a handler? */
setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */
luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */
}
else { /* no handler at all; abort */
if (G(L)->panic) { /* panic function? */
lua_unlock(L);
G(L)->panic(L); /* call it (last chance to jump out) */
}
abort();
}
}
}
int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
unsigned short oldnCcalls = L->nCcalls;
struct lua_longjmp lj;
lj.status = LUA_OK;
lj.previous = L->errorJmp; /* chain new error handler */
L->errorJmp = &lj;
LUAI_TRY(L, &lj,
(*f)(L, ud);
);
L->errorJmp = lj.previous; /* restore old error handler */
L->nCcalls = oldnCcalls;
return lj.status;
}
/* }====================================================== */
static void correctstack (lua_State *L, TValue *oldstack) {
CallInfo *ci;
GCObject *up;
L->top = (L->top - oldstack) + L->stack;
for (up = L->openupval; up != NULL; up = up->gch.next)
gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;
for (ci = L->ci; ci != NULL; ci = ci->previous) {
ci->top = (ci->top - oldstack) + L->stack;
ci->func = (ci->func - oldstack) + L->stack;
if (isLua(ci))
ci->u.l.base = (ci->u.l.base - oldstack) + L->stack;
}
}
/* some space for error handling */
#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
void luaD_reallocstack (lua_State *L, int newsize) {
TValue *oldstack = L->stack;
int lim = L->stacksize;
lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
for (; lim < newsize; lim++)
setnilvalue(L->stack + lim); /* erase new segment */
L->stacksize = newsize;
L->stack_last = L->stack + newsize - EXTRA_STACK;
correctstack(L, oldstack);
}
void luaD_growstack (lua_State *L, int n) {
int size = L->stacksize;
if (size > LUAI_MAXSTACK) /* error after extra size? */
luaD_throw(L, LUA_ERRERR);
else {
int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
int newsize = 2 * size;
if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
if (newsize < needed) newsize = needed;
if (newsize > LUAI_MAXSTACK) { /* stack overflow? */
luaD_reallocstack(L, ERRORSTACKSIZE);
luaG_runerror(L, "stack overflow");
}
else
luaD_reallocstack(L, newsize);
}
}
static int stackinuse (lua_State *L) {
CallInfo *ci;
StkId lim = L->top;
for (ci = L->ci; ci != NULL; ci = ci->previous) {
lua_assert(ci->top <= L->stack_last);
if (lim < ci->top) lim = ci->top;
}
return cast_int(lim - L->stack) + 1; /* part of stack in use */
}
void luaD_shrinkstack (lua_State *L) {
int inuse = stackinuse(L);
int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */
goodsize >= L->stacksize) /* would grow instead of shrink? */
condmovestack(L); /* don't change stack (change only for debugging) */
else
luaD_reallocstack(L, goodsize); /* shrink it */
}
void luaD_hook (lua_State *L, int event, int line) {
lua_Hook hook = L->hook;
if (hook && L->allowhook) {
CallInfo *ci = L->ci;
ptrdiff_t top = savestack(L, L->top);
ptrdiff_t ci_top = savestack(L, ci->top);
lua_Debug ar;
ar.event = event;
ar.currentline = line;
ar.i_ci = ci;
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
L->allowhook = 0; /* cannot call hooks inside a hook */
ci->callstatus |= CIST_HOOKED;
lua_unlock(L);
(*hook)(L, &ar);
lua_lock(L);
lua_assert(!L->allowhook);
L->allowhook = 1;
ci->top = restorestack(L, ci_top);
L->top = restorestack(L, top);
ci->callstatus &= ~CIST_HOOKED;
}
}
static void callhook (lua_State *L, CallInfo *ci) {
int hook = LUA_HOOKCALL;
ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
if (isLua(ci->previous) &&
GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
ci->callstatus |= CIST_TAIL;
hook = LUA_HOOKTAILCALL;
}
luaD_hook(L, hook, -1);
ci->u.l.savedpc--; /* correct 'pc' */
}
static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
int i;
int nfixargs = p->numparams;
StkId base, fixed;
lua_assert(actual >= nfixargs);
/* move fixed parameters to final position */
luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */
fixed = L->top - actual; /* first fixed argument */
base = L->top; /* final position of first argument */
for (i=0; i<nfixargs; i++) {
setobjs2s(L, L->top++, fixed + i);
setnilvalue(fixed + i);
}
return base;
}
static StkId tryfuncTM (lua_State *L, StkId func) {
const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
StkId p;
ptrdiff_t funcr = savestack(L, func);
if (!ttisfunction(tm))
luaG_typeerror(L, func, "call");
/* Open a hole inside the stack at `func' */
for (p = L->top; p > func; p--) setobjs2s(L, p, p-1);
incr_top(L);
func = restorestack(L, funcr); /* previous call may change stack */
setobj2s(L, func, tm); /* tag method is the new function to be called */
return func;
}
#define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L)))
/*
** returns true if function has been executed (C function)
*/
int luaD_precall (lua_State *L, StkId func, int nresults) {
lua_CFunction f;
CallInfo *ci;
int n; /* number of arguments (Lua) or returns (C) */
ptrdiff_t funcr = savestack(L, func);
switch (ttype(func)) {
case LUA_TLCF: /* light C function */
f = fvalue(func);
goto Cfunc;
case LUA_TCCL: { /* C closure */
f = clCvalue(func)->f;
Cfunc:
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = restorestack(L, funcr);
ci->top = L->top + LUA_MINSTACK;
lua_assert(ci->top <= L->stack_last);
ci->callstatus = 0;
luaC_checkGC(L); /* stack grow uses memory */
if (L->hookmask & LUA_MASKCALL)
luaD_hook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
n = (*f)(L); /* do the actual call */
lua_lock(L);
api_checknelems(L, n);
luaD_poscall(L, L->top - n);
return 1;
}
case LUA_TLCL: { /* Lua function: prepare its call */
StkId base;
Proto *p = clLvalue(func)->p;
n = cast_int(L->top - func) - 1; /* number of real arguments */
luaD_checkstack(L, p->maxstacksize);
for (; n < p->numparams; n++)
setnilvalue(L->top++); /* complete missing arguments */
if (!p->is_vararg) {
func = restorestack(L, funcr);
base = func + 1;
}
else {
base = adjust_varargs(L, p, n);
func = restorestack(L, funcr); /* previous call can change stack */
}
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = func;
ci->u.l.base = base;
ci->top = base + p->maxstacksize;
lua_assert(ci->top <= L->stack_last);
ci->u.l.savedpc = p->code; /* starting point */
ci->callstatus = CIST_LUA;
L->top = ci->top;
luaC_checkGC(L); /* stack grow uses memory */
if (L->hookmask & LUA_MASKCALL)
callhook(L, ci);
return 0;
}
default: { /* not a function */
func = tryfuncTM(L, func); /* retry with 'function' tag method */
return luaD_precall(L, func, nresults); /* now it must be a function */
}
}
}
int luaD_poscall (lua_State *L, StkId firstResult) {
StkId res;
int wanted, i;
CallInfo *ci = L->ci;
if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
if (L->hookmask & LUA_MASKRET) {
ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
luaD_hook(L, LUA_HOOKRET, -1);
firstResult = restorestack(L, fr);
}
L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
}
res = ci->func; /* res == final position of 1st result */
wanted = ci->nresults;
L->ci = ci = ci->previous; /* back to caller */
/* move results to correct place */
for (i = wanted; i != 0 && firstResult < L->top; i--)
setobjs2s(L, res++, firstResult++);
while (i-- > 0)
setnilvalue(res++);
L->top = res;
return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
}
/*
** Call a function (C or Lua). The function to be called is at *func.
** The arguments are on the stack, right after the function.
** When returns, all the results are on the stack, starting at the original
** function position.
*/
void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) {
if (++L->nCcalls >= LUAI_MAXCCALLS) {
if (L->nCcalls == LUAI_MAXCCALLS)
luaG_runerror(L, "C stack overflow");
else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3)))
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
}
if (!allowyield) L->nny++;
if (!luaD_precall(L, func, nResults)) /* is a Lua function? */
luaV_execute(L); /* call it */
if (!allowyield) L->nny--;
L->nCcalls--;
}
static void finishCcall (lua_State *L) {
CallInfo *ci = L->ci;
int n;
lua_assert(ci->u.c.k != NULL); /* must have a continuation */
lua_assert(L->nny == 0);
if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */
ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */
L->errfunc = ci->u.c.old_errfunc;
}
/* finish 'lua_callk'/'lua_pcall' */
adjustresults(L, ci->nresults);
/* call continuation function */
if (!(ci->callstatus & CIST_STAT)) /* no call status? */
ci->u.c.status = LUA_YIELD; /* 'default' status */
lua_assert(ci->u.c.status != LUA_OK);
ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED;
lua_unlock(L);
n = (*ci->u.c.k)(L);
lua_lock(L);
api_checknelems(L, n);
/* finish 'luaD_precall' */
luaD_poscall(L, L->top - n);
}
static void unroll (lua_State *L, void *ud) {
UNUSED(ud);
for (;;) {
if (L->ci == &L->base_ci) /* stack is empty? */
return; /* coroutine finished normally */
if (!isLua(L->ci)) /* C function? */
finishCcall(L);
else { /* Lua function */
luaV_finishOp(L); /* finish interrupted instruction */
luaV_execute(L); /* execute down to higher C 'boundary' */
}
}
}
/*
** check whether thread has a suspended protected call
*/
static CallInfo *findpcall (lua_State *L) {
CallInfo *ci;
for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */
if (ci->callstatus & CIST_YPCALL)
return ci;
}
return NULL; /* no pending pcall */
}
static int recover (lua_State *L, int status) {
StkId oldtop;
CallInfo *ci = findpcall(L);
if (ci == NULL) return 0; /* no recovery point */
/* "finish" luaD_pcall */
oldtop = restorestack(L, ci->extra);
luaF_close(L, oldtop);
seterrorobj(L, status, oldtop);
L->ci = ci;
L->allowhook = ci->u.c.old_allowhook;
L->nny = 0; /* should be zero to be yieldable */
luaD_shrinkstack(L);
L->errfunc = ci->u.c.old_errfunc;
ci->callstatus |= CIST_STAT; /* call has error status */
ci->u.c.status = status; /* (here it is) */
return 1; /* continue running the coroutine */
}
/*
** signal an error in the call to 'resume', not in the execution of the
** coroutine itself. (Such errors should not be handled by any coroutine
** error handler and should not kill the coroutine.)
*/
static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) {
L->top = firstArg; /* remove args from the stack */
setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */
api_incr_top(L);
luaD_throw(L, -1); /* jump back to 'lua_resume' */
}
/*
** do the work for 'lua_resume' in protected mode
*/
static void resume (lua_State *L, void *ud) {
int nCcalls = L->nCcalls;
StkId firstArg = cast(StkId, ud);
CallInfo *ci = L->ci;
if (nCcalls >= LUAI_MAXCCALLS)
resume_error(L, "C stack overflow", firstArg);
if (L->status == LUA_OK) { /* may be starting a coroutine */
if (ci != &L->base_ci) /* not in base level? */
resume_error(L, "cannot resume non-suspended coroutine", firstArg);
/* coroutine is in base level; start running it */
if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */
luaV_execute(L); /* call it */
}
else if (L->status != LUA_YIELD)
resume_error(L, "cannot resume dead coroutine", firstArg);
else { /* resuming from previous yield */
L->status = LUA_OK;
ci->func = restorestack(L, ci->extra);
if (isLua(ci)) /* yielded inside a hook? */
luaV_execute(L); /* just continue running Lua code */
else { /* 'common' yield */
if (ci->u.c.k != NULL) { /* does it have a continuation? */
int n;
ci->u.c.status = LUA_YIELD; /* 'default' status */
ci->callstatus |= CIST_YIELDED;
lua_unlock(L);
n = (*ci->u.c.k)(L); /* call continuation */
lua_lock(L);
api_checknelems(L, n);
firstArg = L->top - n; /* yield results come from continuation */
}
luaD_poscall(L, firstArg); /* finish 'luaD_precall' */
}
unroll(L, NULL);
}
lua_assert(nCcalls == L->nCcalls);
}
LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
int status;
int oldnny = L->nny; /* save 'nny' */
lua_lock(L);
luai_userstateresume(L, nargs);
L->nCcalls = (from) ? from->nCcalls + 1 : 1;
L->nny = 0; /* allow yields */
api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs);
status = luaD_rawrunprotected(L, resume, L->top - nargs);
if (status == -1) /* error calling 'lua_resume'? */
status = LUA_ERRRUN;
else { /* yield or regular error */
while (status != LUA_OK && status != LUA_YIELD) { /* error? */
if (recover(L, status)) /* recover point? */
status = luaD_rawrunprotected(L, unroll, NULL); /* run continuation */
else { /* unrecoverable error */
L->status = cast_byte(status); /* mark thread as `dead' */
seterrorobj(L, status, L->top);
L->ci->top = L->top;
break;
}
}
lua_assert(status == L->status);
}
L->nny = oldnny; /* restore 'nny' */
L->nCcalls--;
lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
lua_unlock(L);
return status;
}
LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) {
CallInfo *ci = L->ci;
luai_userstateyield(L, nresults);
lua_lock(L);
api_checknelems(L, nresults);
if (L->nny > 0) {
if (L != G(L)->mainthread)
luaG_runerror(L, "attempt to yield across a C-call boundary");
else
luaG_runerror(L, "attempt to yield from outside a coroutine");
}
L->status = LUA_YIELD;
ci->extra = savestack(L, ci->func); /* save current 'func' */
if (isLua(ci)) { /* inside a hook? */
api_check(L, k == NULL, "hooks cannot continue after yielding");
}
else {
if ((ci->u.c.k = k) != NULL) /* is there a continuation? */
ci->u.c.ctx = ctx; /* save context */
ci->func = L->top - nresults - 1; /* protect stack below results */
luaD_throw(L, LUA_YIELD);
}
lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
lua_unlock(L);
return 0; /* return to 'luaD_hook' */
}
int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t old_top, ptrdiff_t ef) {
int status;
CallInfo *old_ci = L->ci;
lu_byte old_allowhooks = L->allowhook;
unsigned short old_nny = L->nny;
ptrdiff_t old_errfunc = L->errfunc;
L->errfunc = ef;
status = luaD_rawrunprotected(L, func, u);
if (status != LUA_OK) { /* an error occurred? */
StkId oldtop = restorestack(L, old_top);
luaF_close(L, oldtop); /* close possible pending closures */
seterrorobj(L, status, oldtop);
L->ci = old_ci;
L->allowhook = old_allowhooks;
L->nny = old_nny;
luaD_shrinkstack(L);
}
L->errfunc = old_errfunc;
return status;
}
/*
** Execute a protected parser.
*/
struct SParser { /* data to `f_parser' */
ZIO *z;
Mbuffer buff; /* dynamic structure used by the scanner */
Dyndata dyd; /* dynamic structures used by the parser */
const char *mode;
const char *name;
};
static void checkmode (lua_State *L, const char *mode, const char *x) {
if (mode && strchr(mode, x[0]) == NULL) {
luaO_pushfstring(L,
"attempt to load a %s chunk (mode is " LUA_QS ")", x, mode);
luaD_throw(L, LUA_ERRSYNTAX);
}
}
static void f_parser (lua_State *L, void *ud) {
int i;
Closure *cl;
struct SParser *p = cast(struct SParser *, ud);
int c = zgetc(p->z); /* read first character */
if (c == LUA_SIGNATURE[0]) {
checkmode(L, p->mode, "binary");
cl = luaU_undump(L, p->z, &p->buff, p->name);
}
else {
checkmode(L, p->mode, "text");
cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
}
lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
for (i = 0; i < cl->l.nupvalues; i++) { /* initialize upvalues */
UpVal *up = luaF_newupval(L);
cl->l.upvals[i] = up;
luaC_objbarrier(L, cl, up);
}
}
int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
const char *mode) {
struct SParser p;
int status;
L->nny++; /* cannot yield during parsing */
p.z = z; p.name = name; p.mode = mode;
p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0;
p.dyd.gt.arr = NULL; p.dyd.gt.size = 0;
p.dyd.label.arr = NULL; p.dyd.label.size = 0;
luaZ_initbuffer(L, &p.buff);
status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc);
luaZ_freebuffer(L, &p.buff);
luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size);
luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size);
luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size);
L->nny--;
return status;
}

46
vendor/lite/src/lib/lua52/ldo.h vendored Normal file
View file

@ -0,0 +1,46 @@
/*
** $Id: ldo.h,v 2.20.1.1 2013/04/12 18:48:47 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
#ifndef ldo_h
#define ldo_h
#include "lobject.h"
#include "lstate.h"
#include "lzio.h"
#define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \
luaD_growstack(L, n); else condmovestack(L);
#define incr_top(L) {L->top++; luaD_checkstack(L,0);}
#define savestack(L,p) ((char *)(p) - (char *)L->stack)
#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
/* type of protected functions, to be ran by `runprotected' */
typedef void (*Pfunc) (lua_State *L, void *ud);
LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name,
const char *mode);
LUAI_FUNC void luaD_hook (lua_State *L, int event, int line);
LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults,
int allowyield);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t oldtop, ptrdiff_t ef);
LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);
LUAI_FUNC void luaD_shrinkstack (lua_State *L);
LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
#endif

173
vendor/lite/src/lib/lua52/ldump.c vendored Normal file
View file

@ -0,0 +1,173 @@
/*
** $Id: ldump.c,v 2.17.1.1 2013/04/12 18:48:47 roberto Exp $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/
#include <stddef.h>
#define ldump_c
#define LUA_CORE
#include "lua.h"
#include "lobject.h"
#include "lstate.h"
#include "lundump.h"
typedef struct {
lua_State* L;
lua_Writer writer;
void* data;
int strip;
int status;
} DumpState;
#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
static void DumpBlock(const void* b, size_t size, DumpState* D)
{
if (D->status==0)
{
lua_unlock(D->L);
D->status=(*D->writer)(D->L,b,size,D->data);
lua_lock(D->L);
}
}
static void DumpChar(int y, DumpState* D)
{
char x=(char)y;
DumpVar(x,D);
}
static void DumpInt(int x, DumpState* D)
{
DumpVar(x,D);
}
static void DumpNumber(lua_Number x, DumpState* D)
{
DumpVar(x,D);
}
static void DumpVector(const void* b, int n, size_t size, DumpState* D)
{
DumpInt(n,D);
DumpMem(b,n,size,D);
}
static void DumpString(const TString* s, DumpState* D)
{
if (s==NULL)
{
size_t size=0;
DumpVar(size,D);
}
else
{
size_t size=s->tsv.len+1; /* include trailing '\0' */
DumpVar(size,D);
DumpBlock(getstr(s),size*sizeof(char),D);
}
}
#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
static void DumpFunction(const Proto* f, DumpState* D);
static void DumpConstants(const Proto* f, DumpState* D)
{
int i,n=f->sizek;
DumpInt(n,D);
for (i=0; i<n; i++)
{
const TValue* o=&f->k[i];
DumpChar(ttypenv(o),D);
switch (ttypenv(o))
{
case LUA_TNIL:
break;
case LUA_TBOOLEAN:
DumpChar(bvalue(o),D);
break;
case LUA_TNUMBER:
DumpNumber(nvalue(o),D);
break;
case LUA_TSTRING:
DumpString(rawtsvalue(o),D);
break;
default: lua_assert(0);
}
}
n=f->sizep;
DumpInt(n,D);
for (i=0; i<n; i++) DumpFunction(f->p[i],D);
}
static void DumpUpvalues(const Proto* f, DumpState* D)
{
int i,n=f->sizeupvalues;
DumpInt(n,D);
for (i=0; i<n; i++)
{
DumpChar(f->upvalues[i].instack,D);
DumpChar(f->upvalues[i].idx,D);
}
}
static void DumpDebug(const Proto* f, DumpState* D)
{
int i,n;
DumpString((D->strip) ? NULL : f->source,D);
n= (D->strip) ? 0 : f->sizelineinfo;
DumpVector(f->lineinfo,n,sizeof(int),D);
n= (D->strip) ? 0 : f->sizelocvars;
DumpInt(n,D);
for (i=0; i<n; i++)
{
DumpString(f->locvars[i].varname,D);
DumpInt(f->locvars[i].startpc,D);
DumpInt(f->locvars[i].endpc,D);
}
n= (D->strip) ? 0 : f->sizeupvalues;
DumpInt(n,D);
for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D);
}
static void DumpFunction(const Proto* f, DumpState* D)
{
DumpInt(f->linedefined,D);
DumpInt(f->lastlinedefined,D);
DumpChar(f->numparams,D);
DumpChar(f->is_vararg,D);
DumpChar(f->maxstacksize,D);
DumpCode(f,D);
DumpConstants(f,D);
DumpUpvalues(f,D);
DumpDebug(f,D);
}
static void DumpHeader(DumpState* D)
{
lu_byte h[LUAC_HEADERSIZE];
luaU_header(h);
DumpBlock(h,LUAC_HEADERSIZE,D);
}
/*
** dump Lua function as precompiled chunk
*/
int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
{
DumpState D;
D.L=L;
D.writer=w;
D.data=data;
D.strip=strip;
D.status=0;
DumpHeader(&D);
DumpFunction(f,&D);
return D.status;
}

161
vendor/lite/src/lib/lua52/lfunc.c vendored Normal file
View file

@ -0,0 +1,161 @@
/*
** $Id: lfunc.c,v 2.30.1.1 2013/04/12 18:48:47 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
#include <stddef.h>
#define lfunc_c
#define LUA_CORE
#include "lua.h"
#include "lfunc.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
Closure *luaF_newCclosure (lua_State *L, int n) {
Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl;
c->c.nupvalues = cast_byte(n);
return c;
}
Closure *luaF_newLclosure (lua_State *L, int n) {
Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl;
c->l.p = NULL;
c->l.nupvalues = cast_byte(n);
while (n--) c->l.upvals[n] = NULL;
return c;
}
UpVal *luaF_newupval (lua_State *L) {
UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv;
uv->v = &uv->u.value;
setnilvalue(uv->v);
return uv;
}
UpVal *luaF_findupval (lua_State *L, StkId level) {
global_State *g = G(L);
GCObject **pp = &L->openupval;
UpVal *p;
UpVal *uv;
while (*pp != NULL && (p = gco2uv(*pp))->v >= level) {
GCObject *o = obj2gco(p);
lua_assert(p->v != &p->u.value);
lua_assert(!isold(o) || isold(obj2gco(L)));
if (p->v == level) { /* found a corresponding upvalue? */
if (isdead(g, o)) /* is it dead? */
changewhite(o); /* resurrect it */
return p;
}
pp = &p->next;
}
/* not found: create a new one */
uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv;
uv->v = level; /* current value lives in the stack */
uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
uv->u.l.next = g->uvhead.u.l.next;
uv->u.l.next->u.l.prev = uv;
g->uvhead.u.l.next = uv;
lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
return uv;
}
static void unlinkupval (UpVal *uv) {
lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */
uv->u.l.prev->u.l.next = uv->u.l.next;
}
void luaF_freeupval (lua_State *L, UpVal *uv) {
if (uv->v != &uv->u.value) /* is it open? */
unlinkupval(uv); /* remove from open list */
luaM_free(L, uv); /* free upvalue */
}
void luaF_close (lua_State *L, StkId level) {
UpVal *uv;
global_State *g = G(L);
while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) {
GCObject *o = obj2gco(uv);
lua_assert(!isblack(o) && uv->v != &uv->u.value);
L->openupval = uv->next; /* remove from `open' list */
if (isdead(g, o))
luaF_freeupval(L, uv); /* free upvalue */
else {
unlinkupval(uv); /* remove upvalue from 'uvhead' list */
setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */
uv->v = &uv->u.value; /* now current value lives here */
gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */
g->allgc = o;
luaC_checkupvalcolor(g, uv);
}
}
}
Proto *luaF_newproto (lua_State *L) {
Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p;
f->k = NULL;
f->sizek = 0;
f->p = NULL;
f->sizep = 0;
f->code = NULL;
f->cache = NULL;
f->sizecode = 0;
f->lineinfo = NULL;
f->sizelineinfo = 0;
f->upvalues = NULL;
f->sizeupvalues = 0;
f->numparams = 0;
f->is_vararg = 0;
f->maxstacksize = 0;
f->locvars = NULL;
f->sizelocvars = 0;
f->linedefined = 0;
f->lastlinedefined = 0;
f->source = NULL;
return f;
}
void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->code, f->sizecode);
luaM_freearray(L, f->p, f->sizep);
luaM_freearray(L, f->k, f->sizek);
luaM_freearray(L, f->lineinfo, f->sizelineinfo);
luaM_freearray(L, f->locvars, f->sizelocvars);
luaM_freearray(L, f->upvalues, f->sizeupvalues);
luaM_free(L, f);
}
/*
** Look for n-th local variable at line `line' in function `func'.
** Returns NULL if not found.
*/
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
int i;
for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
if (pc < f->locvars[i].endpc) { /* is variable active? */
local_number--;
if (local_number == 0)
return getstr(f->locvars[i].varname);
}
}
return NULL; /* not found */
}

33
vendor/lite/src/lib/lua52/lfunc.h vendored Normal file
View file

@ -0,0 +1,33 @@
/*
** $Id: lfunc.h,v 2.8.1.1 2013/04/12 18:48:47 roberto Exp $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
#ifndef lfunc_h
#define lfunc_h
#include "lobject.h"
#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
cast(int, sizeof(TValue)*((n)-1)))
#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
cast(int, sizeof(TValue *)*((n)-1)))
LUAI_FUNC Proto *luaF_newproto (lua_State *L);
LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems);
LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems);
LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
LUAI_FUNC void luaF_close (lua_State *L, StkId level);
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
int pc);
#endif

1220
vendor/lite/src/lib/lua52/lgc.c vendored Normal file

File diff suppressed because it is too large Load diff

157
vendor/lite/src/lib/lua52/lgc.h vendored Normal file
View file

@ -0,0 +1,157 @@
/*
** $Id: lgc.h,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
#ifndef lgc_h
#define lgc_h
#include "lobject.h"
#include "lstate.h"
/*
** Collectable objects may have one of three colors: white, which
** means the object is not marked; gray, which means the
** object is marked, but its references may be not marked; and
** black, which means that the object and all its references are marked.
** The main invariant of the garbage collector, while marking objects,
** is that a black object can never point to a white one. Moreover,
** any gray object must be in a "gray list" (gray, grayagain, weak,
** allweak, ephemeron) so that it can be visited again before finishing
** the collection cycle. These lists have no meaning when the invariant
** is not being enforced (e.g., sweep phase).
*/
/* how much to allocate before next GC step */
#if !defined(GCSTEPSIZE)
/* ~100 small strings */
#define GCSTEPSIZE (cast_int(100 * sizeof(TString)))
#endif
/*
** Possible states of the Garbage Collector
*/
#define GCSpropagate 0
#define GCSatomic 1
#define GCSsweepstring 2
#define GCSsweepudata 3
#define GCSsweep 4
#define GCSpause 5
#define issweepphase(g) \
(GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep)
#define isgenerational(g) ((g)->gckind == KGC_GEN)
/*
** macros to tell when main invariant (white objects cannot point to black
** ones) must be kept. During a non-generational collection, the sweep
** phase may break the invariant, as objects turned white may point to
** still-black objects. The invariant is restored when sweep ends and
** all objects are white again. During a generational collection, the
** invariant must be kept all times.
*/
#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic)
/*
** Outside the collector, the state in generational mode is kept in
** 'propagate', so 'keepinvariant' is always true.
*/
#define keepinvariantout(g) \
check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \
g->gcstate <= GCSatomic)
/*
** some useful bit tricks
*/
#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m)))
#define setbits(x,m) ((x) |= (m))
#define testbits(x,m) ((x) & (m))
#define bitmask(b) (1<<(b))
#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
#define l_setbit(x,b) setbits(x, bitmask(b))
#define resetbit(x,b) resetbits(x, bitmask(b))
#define testbit(x,b) testbits(x, bitmask(b))
/* Layout for bit use in `marked' field: */
#define WHITE0BIT 0 /* object is white (type 0) */
#define WHITE1BIT 1 /* object is white (type 1) */
#define BLACKBIT 2 /* object is black */
#define FINALIZEDBIT 3 /* object has been separated for finalization */
#define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */
#define FIXEDBIT 5 /* object is fixed (should not be collected) */
#define OLDBIT 6 /* object is old (only in generational mode) */
/* bit 7 is currently used by tests (luaL_checkmemory) */
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
#define iswhite(x) testbits((x)->gch.marked, WHITEBITS)
#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
#define isgray(x) /* neither white nor black */ \
(!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT)))
#define isold(x) testbit((x)->gch.marked, OLDBIT)
/* MOVE OLD rule: whenever an object is moved to the beginning of
a GC list, its old bit must be cleared */
#define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT)
#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked)
#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
#define luaC_condGC(L,c) \
{if (G(L)->GCdebt > 0) {c;}; condchangemem(L);}
#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);)
#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
luaC_barrier_(L,obj2gco(p),gcvalue(v)); }
#define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
luaC_barrierback_(L,p); }
#define luaC_objbarrier(L,p,o) \
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
luaC_barrier_(L,obj2gco(p),obj2gco(o)); }
#define luaC_objbarrierback(L,p,o) \
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); }
#define luaC_barrierproto(L,p,c) \
{ if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); }
LUAI_FUNC void luaC_freeallobjects (lua_State *L);
LUAI_FUNC void luaC_step (lua_State *L);
LUAI_FUNC void luaC_forcestep (lua_State *L);
LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz,
GCObject **list, int offset);
LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c);
LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv);
LUAI_FUNC void luaC_changemode (lua_State *L, int mode);
#endif

67
vendor/lite/src/lib/lua52/linit.c vendored Normal file
View file

@ -0,0 +1,67 @@
/*
** $Id: linit.c,v 1.32.1.1 2013/04/12 18:48:47 roberto Exp $
** Initialization of libraries for lua.c and other clients
** See Copyright Notice in lua.h
*/
/*
** If you embed Lua in your program and need to open the standard
** libraries, call luaL_openlibs in your program. If you need a
** different set of libraries, copy this file to your project and edit
** it to suit your needs.
*/
#define linit_c
#define LUA_LIB
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
/*
** these libs are loaded by lua.c and are readily available to any Lua
** program
*/
static const luaL_Reg loadedlibs[] = {
{"_G", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_COLIBNAME, luaopen_coroutine},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_BITLIBNAME, luaopen_bit32},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
{NULL, NULL}
};
/*
** these libs are preloaded and must be required before used
*/
static const luaL_Reg preloadedlibs[] = {
{NULL, NULL}
};
LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib;
/* call open functions from 'loadedlibs' and set results to global table */
for (lib = loadedlibs; lib->func; lib++) {
luaL_requiref(L, lib->name, lib->func, 1);
lua_pop(L, 1); /* remove lib */
}
/* add open functions from 'preloadedlibs' into 'package.preload' table */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
for (lib = preloadedlibs; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_setfield(L, -2, lib->name);
}
lua_pop(L, 1); /* remove _PRELOAD table */
}

666
vendor/lite/src/lib/lua52/liolib.c vendored Normal file
View file

@ -0,0 +1,666 @@
/*
** $Id: liolib.c,v 2.112.1.1 2013/04/12 18:48:47 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
/*
** This definition must come before the inclusion of 'stdio.h'; it
** should not affect non-POSIX systems
*/
#if !defined(_FILE_OFFSET_BITS)
#define _LARGEFILE_SOURCE 1
#define _FILE_OFFSET_BITS 64
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define liolib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#if !defined(lua_checkmode)
/*
** Check whether 'mode' matches '[rwa]%+?b?'.
** Change this macro to accept other modes for 'fopen' besides
** the standard ones.
*/
#define lua_checkmode(mode) \
(*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \
(*mode != '+' || ++mode) && /* skip if char is '+' */ \
(*mode != 'b' || ++mode) && /* skip if char is 'b' */ \
(*mode == '\0'))
#endif
/*
** {======================================================
** lua_popen spawns a new process connected to the current
** one through the file streams.
** =======================================================
*/
#if !defined(lua_popen) /* { */
#if defined(LUA_USE_POPEN) /* { */
#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
#define lua_pclose(L,file) ((void)L, pclose(file))
#elif defined(LUA_WIN) /* }{ */
#define lua_popen(L,c,m) ((void)L, _popen(c,m))
#define lua_pclose(L,file) ((void)L, _pclose(file))
#else /* }{ */
#define lua_popen(L,c,m) ((void)((void)c, m), \
luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
#define lua_pclose(L,file) ((void)((void)L, file), -1)
#endif /* } */
#endif /* } */
/* }====================================================== */
/*
** {======================================================
** lua_fseek: configuration for longer offsets
** =======================================================
*/
#if !defined(lua_fseek) && !defined(LUA_ANSI) /* { */
#if defined(LUA_USE_POSIX) /* { */
#define l_fseek(f,o,w) fseeko(f,o,w)
#define l_ftell(f) ftello(f)
#define l_seeknum off_t
#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \
&& defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */
/* Windows (but not DDK) and Visual C++ 2005 or higher */
#define l_fseek(f,o,w) _fseeki64(f,o,w)
#define l_ftell(f) _ftelli64(f)
#define l_seeknum __int64
#endif /* } */
#endif /* } */
#if !defined(l_fseek) /* default definitions */
#define l_fseek(f,o,w) fseek(f,o,w)
#define l_ftell(f) ftell(f)
#define l_seeknum long
#endif
/* }====================================================== */
#define IO_PREFIX "_IO_"
#define IO_INPUT (IO_PREFIX "input")
#define IO_OUTPUT (IO_PREFIX "output")
typedef luaL_Stream LStream;
#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
#define isclosed(p) ((p)->closef == NULL)
static int io_type (lua_State *L) {
LStream *p;
luaL_checkany(L, 1);
p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE);
if (p == NULL)
lua_pushnil(L); /* not a file */
else if (isclosed(p))
lua_pushliteral(L, "closed file");
else
lua_pushliteral(L, "file");
return 1;
}
static int f_tostring (lua_State *L) {
LStream *p = tolstream(L);
if (isclosed(p))
lua_pushliteral(L, "file (closed)");
else
lua_pushfstring(L, "file (%p)", p->f);
return 1;
}
static FILE *tofile (lua_State *L) {
LStream *p = tolstream(L);
if (isclosed(p))
luaL_error(L, "attempt to use a closed file");
lua_assert(p->f);
return p->f;
}
/*
** When creating file handles, always creates a `closed' file handle
** before opening the actual file; so, if there is a memory error, the
** file is not left opened.
*/
static LStream *newprefile (lua_State *L) {
LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
p->closef = NULL; /* mark file handle as 'closed' */
luaL_setmetatable(L, LUA_FILEHANDLE);
return p;
}
static int aux_close (lua_State *L) {
LStream *p = tolstream(L);
lua_CFunction cf = p->closef;
p->closef = NULL; /* mark stream as closed */
return (*cf)(L); /* close it */
}
static int io_close (lua_State *L) {
if (lua_isnone(L, 1)) /* no argument? */
lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */
tofile(L); /* make sure argument is an open stream */
return aux_close(L);
}
static int f_gc (lua_State *L) {
LStream *p = tolstream(L);
if (!isclosed(p) && p->f != NULL)
aux_close(L); /* ignore closed and incompletely open files */
return 0;
}
/*
** function to close regular files
*/
static int io_fclose (lua_State *L) {
LStream *p = tolstream(L);
int res = fclose(p->f);
return luaL_fileresult(L, (res == 0), NULL);
}
static LStream *newfile (lua_State *L) {
LStream *p = newprefile(L);
p->f = NULL;
p->closef = &io_fclose;
return p;
}
static void opencheck (lua_State *L, const char *fname, const char *mode) {
LStream *p = newfile(L);
p->f = fopen(fname, mode);
if (p->f == NULL)
luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno));
}
static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
LStream *p = newfile(L);
const char *md = mode; /* to traverse/check mode */
luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode");
p->f = fopen(filename, mode);
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
}
/*
** function to close 'popen' files
*/
static int io_pclose (lua_State *L) {
LStream *p = tolstream(L);
return luaL_execresult(L, lua_pclose(L, p->f));
}
static int io_popen (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
LStream *p = newprefile(L);
p->f = lua_popen(L, filename, mode);
p->closef = &io_pclose;
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
}
static int io_tmpfile (lua_State *L) {
LStream *p = newfile(L);
p->f = tmpfile();
return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
}
static FILE *getiofile (lua_State *L, const char *findex) {
LStream *p;
lua_getfield(L, LUA_REGISTRYINDEX, findex);
p = (LStream *)lua_touserdata(L, -1);
if (isclosed(p))
luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX));
return p->f;
}
static int g_iofile (lua_State *L, const char *f, const char *mode) {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
if (filename)
opencheck(L, filename, mode);
else {
tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1);
}
lua_setfield(L, LUA_REGISTRYINDEX, f);
}
/* return current value */
lua_getfield(L, LUA_REGISTRYINDEX, f);
return 1;
}
static int io_input (lua_State *L) {
return g_iofile(L, IO_INPUT, "r");
}
static int io_output (lua_State *L) {
return g_iofile(L, IO_OUTPUT, "w");
}
static int io_readline (lua_State *L);
static void aux_lines (lua_State *L, int toclose) {
int i;
int n = lua_gettop(L) - 1; /* number of arguments to read */
/* ensure that arguments will fit here and into 'io_readline' stack */
luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options");
lua_pushvalue(L, 1); /* file handle */
lua_pushinteger(L, n); /* number of arguments to read */
lua_pushboolean(L, toclose); /* close/not close file when finished */
for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1); /* copy arguments */
lua_pushcclosure(L, io_readline, 3 + n);
}
static int f_lines (lua_State *L) {
tofile(L); /* check that it's a valid file handle */
aux_lines(L, 0);
return 1;
}
static int io_lines (lua_State *L) {
int toclose;
if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */
if (lua_isnil(L, 1)) { /* no file name? */
lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */
lua_replace(L, 1); /* put it at index 1 */
tofile(L); /* check that it's a valid file handle */
toclose = 0; /* do not close it after iteration */
}
else { /* open a new file */
const char *filename = luaL_checkstring(L, 1);
opencheck(L, filename, "r");
lua_replace(L, 1); /* put file at index 1 */
toclose = 1; /* close it after iteration */
}
aux_lines(L, toclose);
return 1;
}
/*
** {======================================================
** READ
** =======================================================
*/
static int read_number (lua_State *L, FILE *f) {
lua_Number d;
if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
lua_pushnumber(L, d);
return 1;
}
else {
lua_pushnil(L); /* "result" to be removed */
return 0; /* read fails */
}
}
static int test_eof (lua_State *L, FILE *f) {
int c = getc(f);
ungetc(c, f);
lua_pushlstring(L, NULL, 0);
return (c != EOF);
}
static int read_line (lua_State *L, FILE *f, int chop) {
luaL_Buffer b;
luaL_buffinit(L, &b);
for (;;) {
size_t l;
char *p = luaL_prepbuffer(&b);
if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
luaL_pushresult(&b); /* close buffer */
return (lua_rawlen(L, -1) > 0); /* check whether read something */
}
l = strlen(p);
if (l == 0 || p[l-1] != '\n')
luaL_addsize(&b, l);
else {
luaL_addsize(&b, l - chop); /* chop 'eol' if needed */
luaL_pushresult(&b); /* close buffer */
return 1; /* read at least an `eol' */
}
}
}
#define MAX_SIZE_T (~(size_t)0)
static void read_all (lua_State *L, FILE *f) {
size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */
luaL_Buffer b;
luaL_buffinit(L, &b);
for (;;) {
char *p = luaL_prepbuffsize(&b, rlen);
size_t nr = fread(p, sizeof(char), rlen, f);
luaL_addsize(&b, nr);
if (nr < rlen) break; /* eof? */
else if (rlen <= (MAX_SIZE_T / 4)) /* avoid buffers too large */
rlen *= 2; /* double buffer size at each iteration */
}
luaL_pushresult(&b); /* close buffer */
}
static int read_chars (lua_State *L, FILE *f, size_t n) {
size_t nr; /* number of chars actually read */
char *p;
luaL_Buffer b;
luaL_buffinit(L, &b);
p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */
nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */
luaL_addsize(&b, nr);
luaL_pushresult(&b); /* close buffer */
return (nr > 0); /* true iff read something */
}
static int g_read (lua_State *L, FILE *f, int first) {
int nargs = lua_gettop(L) - 1;
int success;
int n;
clearerr(f);
if (nargs == 0) { /* no arguments? */
success = read_line(L, f, 1);
n = first+1; /* to return 1 result */
}
else { /* ensure stack space for all results and for auxlib's buffer */
luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
success = 1;
for (n = first; nargs-- && success; n++) {
if (lua_type(L, n) == LUA_TNUMBER) {
size_t l = (size_t)lua_tointeger(L, n);
success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
}
else {
const char *p = lua_tostring(L, n);
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) {
case 'n': /* number */
success = read_number(L, f);
break;
case 'l': /* line */
success = read_line(L, f, 1);
break;
case 'L': /* line with end-of-line */
success = read_line(L, f, 0);
break;
case 'a': /* file */
read_all(L, f); /* read entire file */
success = 1; /* always success */
break;
default:
return luaL_argerror(L, n, "invalid format");
}
}
}
}
if (ferror(f))
return luaL_fileresult(L, 0, NULL);
if (!success) {
lua_pop(L, 1); /* remove last result */
lua_pushnil(L); /* push nil instead */
}
return n - first;
}
static int io_read (lua_State *L) {
return g_read(L, getiofile(L, IO_INPUT), 1);
}
static int f_read (lua_State *L) {
return g_read(L, tofile(L), 2);
}
static int io_readline (lua_State *L) {
LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
int i;
int n = (int)lua_tointeger(L, lua_upvalueindex(2));
if (isclosed(p)) /* file is already closed? */
return luaL_error(L, "file is already closed");
lua_settop(L , 1);
for (i = 1; i <= n; i++) /* push arguments to 'g_read' */
lua_pushvalue(L, lua_upvalueindex(3 + i));
n = g_read(L, p->f, 2); /* 'n' is number of results */
lua_assert(n > 0); /* should return at least a nil */
if (!lua_isnil(L, -n)) /* read at least one value? */
return n; /* return them */
else { /* first result is nil: EOF or error */
if (n > 1) { /* is there error information? */
/* 2nd result is error message */
return luaL_error(L, "%s", lua_tostring(L, -n + 1));
}
if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */
lua_settop(L, 0);
lua_pushvalue(L, lua_upvalueindex(1));
aux_close(L); /* close it */
}
return 0;
}
}
/* }====================================================== */
static int g_write (lua_State *L, FILE *f, int arg) {
int nargs = lua_gettop(L) - arg;
int status = 1;
for (; nargs--; arg++) {
if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */
status = status &&
fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
}
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
status = status && (fwrite(s, sizeof(char), l, f) == l);
}
}
if (status) return 1; /* file handle already on stack top */
else return luaL_fileresult(L, status, NULL);
}
static int io_write (lua_State *L) {
return g_write(L, getiofile(L, IO_OUTPUT), 1);
}
static int f_write (lua_State *L) {
FILE *f = tofile(L);
lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */
return g_write(L, f, 2);
}
static int f_seek (lua_State *L) {
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = {"set", "cur", "end", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, "cur", modenames);
lua_Number p3 = luaL_optnumber(L, 3, 0);
l_seeknum offset = (l_seeknum)p3;
luaL_argcheck(L, (lua_Number)offset == p3, 3,
"not an integer in proper range");
op = l_fseek(f, offset, mode[op]);
if (op)
return luaL_fileresult(L, 0, NULL); /* error */
else {
lua_pushnumber(L, (lua_Number)l_ftell(f));
return 1;
}
}
static int f_setvbuf (lua_State *L) {
static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
static const char *const modenames[] = {"no", "full", "line", NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, NULL, modenames);
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
int res = setvbuf(f, NULL, mode[op], sz);
return luaL_fileresult(L, res == 0, NULL);
}
static int io_flush (lua_State *L) {
return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
}
static int f_flush (lua_State *L) {
return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
}
/*
** functions for 'io' library
*/
static const luaL_Reg iolib[] = {
{"close", io_close},
{"flush", io_flush},
{"input", io_input},
{"lines", io_lines},
{"open", io_open},
{"output", io_output},
{"popen", io_popen},
{"read", io_read},
{"tmpfile", io_tmpfile},
{"type", io_type},
{"write", io_write},
{NULL, NULL}
};
/*
** methods for file handles
*/
static const luaL_Reg flib[] = {
{"close", io_close},
{"flush", f_flush},
{"lines", f_lines},
{"read", f_read},
{"seek", f_seek},
{"setvbuf", f_setvbuf},
{"write", f_write},
{"__gc", f_gc},
{"__tostring", f_tostring},
{NULL, NULL}
};
static void createmeta (lua_State *L) {
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */
lua_pop(L, 1); /* pop new metatable */
}
/*
** function to (not) close the standard files stdin, stdout, and stderr
*/
static int io_noclose (lua_State *L) {
LStream *p = tolstream(L);
p->closef = &io_noclose; /* keep file opened */
lua_pushnil(L);
lua_pushliteral(L, "cannot close standard file");
return 2;
}
static void createstdfile (lua_State *L, FILE *f, const char *k,
const char *fname) {
LStream *p = newprefile(L);
p->f = f;
p->closef = &io_noclose;
if (k != NULL) {
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */
}
lua_setfield(L, -2, fname); /* add file to module */
}
LUAMOD_API int luaopen_io (lua_State *L) {
luaL_newlib(L, iolib); /* new module */
createmeta(L);
/* create (and set) default files */
createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, stderr, NULL, "stderr");
return 1;
}

530
vendor/lite/src/lib/lua52/llex.c vendored Normal file
View file

@ -0,0 +1,530 @@
/*
** $Id: llex.c,v 2.63.1.3 2015/02/09 17:56:34 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
#include <locale.h>
#include <string.h>
#define llex_c
#define LUA_CORE
#include "lua.h"
#include "lctype.h"
#include "ldo.h"
#include "llex.h"
#include "lobject.h"
#include "lparser.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "lzio.h"
#define next(ls) (ls->current = zgetc(ls->z))
#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r')
/* ORDER RESERVED */
static const char *const luaX_tokens [] = {
"and", "break", "do", "else", "elseif",
"end", "false", "for", "function", "goto", "if",
"in", "local", "nil", "not", "or", "repeat",
"return", "then", "true", "until", "while",
"..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
"<number>", "<name>", "<string>"
};
#define save_and_next(ls) (save(ls, ls->current), next(ls))
static l_noret lexerror (LexState *ls, const char *msg, int token);
static void save (LexState *ls, int c) {
Mbuffer *b = ls->buff;
if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
size_t newsize;
if (luaZ_sizebuffer(b) >= MAX_SIZET/2)
lexerror(ls, "lexical element too long", 0);
newsize = luaZ_sizebuffer(b) * 2;
luaZ_resizebuffer(ls->L, b, newsize);
}
b->buffer[luaZ_bufflen(b)++] = cast(char, c);
}
void luaX_init (lua_State *L) {
int i;
for (i=0; i<NUM_RESERVED; i++) {
TString *ts = luaS_new(L, luaX_tokens[i]);
luaS_fix(ts); /* reserved words are never collected */
ts->tsv.extra = cast_byte(i+1); /* reserved word */
}
}
const char *luaX_token2str (LexState *ls, int token) {
if (token < FIRST_RESERVED) { /* single-byte symbols? */
lua_assert(token == cast(unsigned char, token));
return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) :
luaO_pushfstring(ls->L, "char(%d)", token);
}
else {
const char *s = luaX_tokens[token - FIRST_RESERVED];
if (token < TK_EOS) /* fixed format (symbols and reserved words)? */
return luaO_pushfstring(ls->L, LUA_QS, s);
else /* names, strings, and numerals */
return s;
}
}
static const char *txtToken (LexState *ls, int token) {
switch (token) {
case TK_NAME:
case TK_STRING:
case TK_NUMBER:
save(ls, '\0');
return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff));
default:
return luaX_token2str(ls, token);
}
}
static l_noret lexerror (LexState *ls, const char *msg, int token) {
char buff[LUA_IDSIZE];
luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE);
msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg);
if (token)
luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token));
luaD_throw(ls->L, LUA_ERRSYNTAX);
}
l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
lexerror(ls, msg, ls->t.token);
}
/*
** creates a new string and anchors it in function's table so that
** it will not be collected until the end of the function's compilation
** (by that time it should be anchored in function's prototype)
*/
TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
lua_State *L = ls->L;
TValue *o; /* entry for `str' */
TString *ts = luaS_newlstr(L, str, l); /* create new string */
setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
o = luaH_set(L, ls->fs->h, L->top - 1);
if (ttisnil(o)) { /* not in use yet? (see 'addK') */
/* boolean value does not need GC barrier;
table has no metatable, so it does not need to invalidate cache */
setbvalue(o, 1); /* t[string] = true */
luaC_checkGC(L);
}
else { /* string already present */
ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */
}
L->top--; /* remove string from stack */
return ts;
}
/*
** increment line number and skips newline sequence (any of
** \n, \r, \n\r, or \r\n)
*/
static void inclinenumber (LexState *ls) {
int old = ls->current;
lua_assert(currIsNewline(ls));
next(ls); /* skip `\n' or `\r' */
if (currIsNewline(ls) && ls->current != old)
next(ls); /* skip `\n\r' or `\r\n' */
if (++ls->linenumber >= MAX_INT)
lexerror(ls, "chunk has too many lines", 0);
}
void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source,
int firstchar) {
ls->decpoint = '.';
ls->L = L;
ls->current = firstchar;
ls->lookahead.token = TK_EOS; /* no look-ahead token */
ls->z = z;
ls->fs = NULL;
ls->linenumber = 1;
ls->lastline = 1;
ls->source = source;
ls->envn = luaS_new(L, LUA_ENV); /* create env name */
luaS_fix(ls->envn); /* never collect this name */
luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
}
/*
** =======================================================
** LEXICAL ANALYZER
** =======================================================
*/
static int check_next (LexState *ls, const char *set) {
if (ls->current == '\0' || !strchr(set, ls->current))
return 0;
save_and_next(ls);
return 1;
}
/*
** change all characters 'from' in buffer to 'to'
*/
static void buffreplace (LexState *ls, char from, char to) {
size_t n = luaZ_bufflen(ls->buff);
char *p = luaZ_buffer(ls->buff);
while (n--)
if (p[n] == from) p[n] = to;
}
#if !defined(getlocaledecpoint)
#define getlocaledecpoint() (localeconv()->decimal_point[0])
#endif
#define buff2d(b,e) luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e)
/*
** in case of format error, try to change decimal point separator to
** the one defined in the current locale and check again
*/
static void trydecpoint (LexState *ls, SemInfo *seminfo) {
char old = ls->decpoint;
ls->decpoint = getlocaledecpoint();
buffreplace(ls, old, ls->decpoint); /* try new decimal separator */
if (!buff2d(ls->buff, &seminfo->r)) {
/* format error with correct decimal point: no more options */
buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
lexerror(ls, "malformed number", TK_NUMBER);
}
}
/* LUA_NUMBER */
/*
** this function is quite liberal in what it accepts, as 'luaO_str2d'
** will reject ill-formed numerals.
*/
static void read_numeral (LexState *ls, SemInfo *seminfo) {
const char *expo = "Ee";
int first = ls->current;
lua_assert(lisdigit(ls->current));
save_and_next(ls);
if (first == '0' && check_next(ls, "Xx")) /* hexadecimal? */
expo = "Pp";
for (;;) {
if (check_next(ls, expo)) /* exponent part? */
check_next(ls, "+-"); /* optional exponent sign */
if (lisxdigit(ls->current) || ls->current == '.')
save_and_next(ls);
else break;
}
save(ls, '\0');
buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
if (!buff2d(ls->buff, &seminfo->r)) /* format error? */
trydecpoint(ls, seminfo); /* try to update decimal point separator */
}
/*
** skip a sequence '[=*[' or ']=*]' and return its number of '='s or
** -1 if sequence is malformed
*/
static int skip_sep (LexState *ls) {
int count = 0;
int s = ls->current;
lua_assert(s == '[' || s == ']');
save_and_next(ls);
while (ls->current == '=') {
save_and_next(ls);
count++;
}
return (ls->current == s) ? count : (-count) - 1;
}
static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
save_and_next(ls); /* skip 2nd `[' */
if (currIsNewline(ls)) /* string starts with a newline? */
inclinenumber(ls); /* skip it */
for (;;) {
switch (ls->current) {
case EOZ:
lexerror(ls, (seminfo) ? "unfinished long string" :
"unfinished long comment", TK_EOS);
break; /* to avoid warnings */
case ']': {
if (skip_sep(ls) == sep) {
save_and_next(ls); /* skip 2nd `]' */
goto endloop;
}
break;
}
case '\n': case '\r': {
save(ls, '\n');
inclinenumber(ls);
if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */
break;
}
default: {
if (seminfo) save_and_next(ls);
else next(ls);
}
}
} endloop:
if (seminfo)
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep),
luaZ_bufflen(ls->buff) - 2*(2 + sep));
}
static void escerror (LexState *ls, int *c, int n, const char *msg) {
int i;
luaZ_resetbuffer(ls->buff); /* prepare error message */
save(ls, '\\');
for (i = 0; i < n && c[i] != EOZ; i++)
save(ls, c[i]);
lexerror(ls, msg, TK_STRING);
}
static int readhexaesc (LexState *ls) {
int c[3], i; /* keep input for error message */
int r = 0; /* result accumulator */
c[0] = 'x'; /* for error message */
for (i = 1; i < 3; i++) { /* read two hexadecimal digits */
c[i] = next(ls);
if (!lisxdigit(c[i]))
escerror(ls, c, i + 1, "hexadecimal digit expected");
r = (r << 4) + luaO_hexavalue(c[i]);
}
return r;
}
static int readdecesc (LexState *ls) {
int c[3], i;
int r = 0; /* result accumulator */
for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */
c[i] = ls->current;
r = 10*r + c[i] - '0';
next(ls);
}
if (r > UCHAR_MAX)
escerror(ls, c, i, "decimal escape too large");
return r;
}
static void read_string (LexState *ls, int del, SemInfo *seminfo) {
save_and_next(ls); /* keep delimiter (for error messages) */
while (ls->current != del) {
switch (ls->current) {
case EOZ:
lexerror(ls, "unfinished string", TK_EOS);
break; /* to avoid warnings */
case '\n':
case '\r':
lexerror(ls, "unfinished string", TK_STRING);
break; /* to avoid warnings */
case '\\': { /* escape sequences */
int c; /* final character to be saved */
next(ls); /* do not save the `\' */
switch (ls->current) {
case 'a': c = '\a'; goto read_save;
case 'b': c = '\b'; goto read_save;
case 'f': c = '\f'; goto read_save;
case 'n': c = '\n'; goto read_save;
case 'r': c = '\r'; goto read_save;
case 't': c = '\t'; goto read_save;
case 'v': c = '\v'; goto read_save;
case 'x': c = readhexaesc(ls); goto read_save;
case '\n': case '\r':
inclinenumber(ls); c = '\n'; goto only_save;
case '\\': case '\"': case '\'':
c = ls->current; goto read_save;
case EOZ: goto no_save; /* will raise an error next loop */
case 'z': { /* zap following span of spaces */
next(ls); /* skip the 'z' */
while (lisspace(ls->current)) {
if (currIsNewline(ls)) inclinenumber(ls);
else next(ls);
}
goto no_save;
}
default: {
if (!lisdigit(ls->current))
escerror(ls, &ls->current, 1, "invalid escape sequence");
/* digital escape \ddd */
c = readdecesc(ls);
goto only_save;
}
}
read_save: next(ls); /* read next character */
only_save: save(ls, c); /* save 'c' */
no_save: break;
}
default:
save_and_next(ls);
}
}
save_and_next(ls); /* skip delimiter */
seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
luaZ_bufflen(ls->buff) - 2);
}
static int llex (LexState *ls, SemInfo *seminfo) {
luaZ_resetbuffer(ls->buff);
for (;;) {
switch (ls->current) {
case '\n': case '\r': { /* line breaks */
inclinenumber(ls);
break;
}
case ' ': case '\f': case '\t': case '\v': { /* spaces */
next(ls);
break;
}
case '-': { /* '-' or '--' (comment) */
next(ls);
if (ls->current != '-') return '-';
/* else is a comment */
next(ls);
if (ls->current == '[') { /* long comment? */
int sep = skip_sep(ls);
luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */
if (sep >= 0) {
read_long_string(ls, NULL, sep); /* skip long comment */
luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */
break;
}
}
/* else short comment */
while (!currIsNewline(ls) && ls->current != EOZ)
next(ls); /* skip until end of line (or end of file) */
break;
}
case '[': { /* long string or simply '[' */
int sep = skip_sep(ls);
if (sep >= 0) {
read_long_string(ls, seminfo, sep);
return TK_STRING;
}
else if (sep == -1) return '[';
else lexerror(ls, "invalid long string delimiter", TK_STRING);
}
case '=': {
next(ls);
if (ls->current != '=') return '=';
else { next(ls); return TK_EQ; }
}
case '<': {
next(ls);
if (ls->current != '=') return '<';
else { next(ls); return TK_LE; }
}
case '>': {
next(ls);
if (ls->current != '=') return '>';
else { next(ls); return TK_GE; }
}
case '~': {
next(ls);
if (ls->current != '=') return '~';
else { next(ls); return TK_NE; }
}
case ':': {
next(ls);
if (ls->current != ':') return ':';
else { next(ls); return TK_DBCOLON; }
}
case '"': case '\'': { /* short literal strings */
read_string(ls, ls->current, seminfo);
return TK_STRING;
}
case '.': { /* '.', '..', '...', or number */
save_and_next(ls);
if (check_next(ls, ".")) {
if (check_next(ls, "."))
return TK_DOTS; /* '...' */
else return TK_CONCAT; /* '..' */
}
else if (!lisdigit(ls->current)) return '.';
/* else go through */
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
read_numeral(ls, seminfo);
return TK_NUMBER;
}
case EOZ: {
return TK_EOS;
}
default: {
if (lislalpha(ls->current)) { /* identifier or reserved word? */
TString *ts;
do {
save_and_next(ls);
} while (lislalnum(ls->current));
ts = luaX_newstring(ls, luaZ_buffer(ls->buff),
luaZ_bufflen(ls->buff));
seminfo->ts = ts;
if (isreserved(ts)) /* reserved word? */
return ts->tsv.extra - 1 + FIRST_RESERVED;
else {
return TK_NAME;
}
}
else { /* single-char tokens (+ - / ...) */
int c = ls->current;
next(ls);
return c;
}
}
}
}
}
void luaX_next (LexState *ls) {
ls->lastline = ls->linenumber;
if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */
ls->t = ls->lookahead; /* use this one */
ls->lookahead.token = TK_EOS; /* and discharge it */
}
else
ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */
}
int luaX_lookahead (LexState *ls) {
lua_assert(ls->lookahead.token == TK_EOS);
ls->lookahead.token = llex(ls, &ls->lookahead.seminfo);
return ls->lookahead.token;
}

78
vendor/lite/src/lib/lua52/llex.h vendored Normal file
View file

@ -0,0 +1,78 @@
/*
** $Id: llex.h,v 1.72.1.1 2013/04/12 18:48:47 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
#ifndef llex_h
#define llex_h
#include "lobject.h"
#include "lzio.h"
#define FIRST_RESERVED 257
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER RESERVED"
*/
enum RESERVED {
/* terminal symbols denoted by reserved words */
TK_AND = FIRST_RESERVED, TK_BREAK,
TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
/* other terminal symbols */
TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS,
TK_NUMBER, TK_NAME, TK_STRING
};
/* number of reserved words */
#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
typedef union {
lua_Number r;
TString *ts;
} SemInfo; /* semantics information */
typedef struct Token {
int token;
SemInfo seminfo;
} Token;
/* state of the lexer plus state of the parser when shared by all
functions */
typedef struct LexState {
int current; /* current character (charint) */
int linenumber; /* input line counter */
int lastline; /* line of last token `consumed' */
Token t; /* current token */
Token lookahead; /* look ahead token */
struct FuncState *fs; /* current function (parser) */
struct lua_State *L;
ZIO *z; /* input stream */
Mbuffer *buff; /* buffer for tokens */
struct Dyndata *dyd; /* dynamic structures used by the parser */
TString *source; /* current source name */
TString *envn; /* environment variable name */
char decpoint; /* locale decimal point */
} LexState;
LUAI_FUNC void luaX_init (lua_State *L);
LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
TString *source, int firstchar);
LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
LUAI_FUNC void luaX_next (LexState *ls);
LUAI_FUNC int luaX_lookahead (LexState *ls);
LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s);
LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);
#endif

309
vendor/lite/src/lib/lua52/llimits.h vendored Normal file
View file

@ -0,0 +1,309 @@
/*
** $Id: llimits.h,v 1.103.1.1 2013/04/12 18:48:47 roberto Exp $
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/
#ifndef llimits_h
#define llimits_h
#include <limits.h>
#include <stddef.h>
#include "lua.h"
typedef unsigned LUA_INT32 lu_int32;
typedef LUAI_UMEM lu_mem;
typedef LUAI_MEM l_mem;
/* chars used as small naturals (so that `char' is reserved for characters) */
typedef unsigned char lu_byte;
#define MAX_SIZET ((size_t)(~(size_t)0)-2)
#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
#define MAX_LMEM ((l_mem) ((MAX_LUMEM >> 1) - 2))
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
/*
** conversion of pointer to integer
** this is for hashing only; there is no problem if the integer
** cannot hold the whole pointer value
*/
#define IntPoint(p) ((unsigned int)(lu_mem)(p))
/* type to ensure maximum alignment */
#if !defined(LUAI_USER_ALIGNMENT_T)
#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
#endif
typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;
/* result of a `usual argument conversion' over lua_Number */
typedef LUAI_UACNUMBER l_uacNumber;
/* internal assertions for in-house debugging */
#if defined(lua_assert)
#define check_exp(c,e) (lua_assert(c), (e))
/* to avoid problems with conditions too long */
#define lua_longassert(c) { if (!(c)) lua_assert(0); }
#else
#define lua_assert(c) ((void)0)
#define check_exp(c,e) (e)
#define lua_longassert(c) ((void)0)
#endif
/*
** assertion for checking API calls
*/
#if !defined(luai_apicheck)
#if defined(LUA_USE_APICHECK)
#include <assert.h>
#define luai_apicheck(L,e) assert(e)
#else
#define luai_apicheck(L,e) lua_assert(e)
#endif
#endif
#define api_check(l,e,msg) luai_apicheck(l,(e) && msg)
#if !defined(UNUSED)
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
#endif
#define cast(t, exp) ((t)(exp))
#define cast_byte(i) cast(lu_byte, (i))
#define cast_num(i) cast(lua_Number, (i))
#define cast_int(i) cast(int, (i))
#define cast_uchar(i) cast(unsigned char, (i))
/*
** non-return type
*/
#if defined(__GNUC__)
#define l_noret void __attribute__((noreturn))
#elif defined(_MSC_VER)
#define l_noret void __declspec(noreturn)
#else
#define l_noret void
#endif
/*
** maximum depth for nested C calls and syntactical nested non-terminals
** in a program. (Value must fit in an unsigned short int.)
*/
#if !defined(LUAI_MAXCCALLS)
#define LUAI_MAXCCALLS 200
#endif
/*
** maximum number of upvalues in a closure (both C and Lua). (Value
** must fit in an unsigned char.)
*/
#define MAXUPVAL UCHAR_MAX
/*
** type for virtual-machine instructions
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
*/
typedef lu_int32 Instruction;
/* maximum stack for a Lua function */
#define MAXSTACK 250
/* minimum size for the string table (must be power of 2) */
#if !defined(MINSTRTABSIZE)
#define MINSTRTABSIZE 32
#endif
/* minimum size for string buffer */
#if !defined(LUA_MINBUFFER)
#define LUA_MINBUFFER 32
#endif
#if !defined(lua_lock)
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
#endif
#if !defined(luai_threadyield)
#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
#endif
/*
** these macros allow user-specific actions on threads when you defined
** LUAI_EXTRASPACE and need to do something extra when a thread is
** created/deleted/resumed/yielded.
*/
#if !defined(luai_userstateopen)
#define luai_userstateopen(L) ((void)L)
#endif
#if !defined(luai_userstateclose)
#define luai_userstateclose(L) ((void)L)
#endif
#if !defined(luai_userstatethread)
#define luai_userstatethread(L,L1) ((void)L)
#endif
#if !defined(luai_userstatefree)
#define luai_userstatefree(L,L1) ((void)L)
#endif
#if !defined(luai_userstateresume)
#define luai_userstateresume(L,n) ((void)L)
#endif
#if !defined(luai_userstateyield)
#define luai_userstateyield(L,n) ((void)L)
#endif
/*
** lua_number2int is a macro to convert lua_Number to int.
** lua_number2integer is a macro to convert lua_Number to lua_Integer.
** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned.
** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number.
** luai_hashnum is a macro to hash a lua_Number value into an integer.
** The hash must be deterministic and give reasonable values for
** both small and large values (outside the range of integers).
*/
#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */
/* trick with Microsoft assembler for X86 */
#define lua_number2int(i,n) __asm {__asm fld n __asm fistp i}
#define lua_number2integer(i,n) lua_number2int(i, n)
#define lua_number2unsigned(i,n) \
{__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;}
#elif defined(LUA_IEEE754TRICK) /* }{ */
/* the next trick should work on any machine using IEEE754 with
a 32-bit int type */
union luai_Cast { double l_d; LUA_INT32 l_p[2]; };
#if !defined(LUA_IEEEENDIAN) /* { */
#define LUAI_EXTRAIEEE \
static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)};
#define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33)
#else
#define LUA_IEEEENDIANLOC LUA_IEEEENDIAN
#define LUAI_EXTRAIEEE /* empty */
#endif /* } */
#define lua_number2int32(i,n,t) \
{ LUAI_EXTRAIEEE \
volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \
(i) = (t)u.l_p[LUA_IEEEENDIANLOC]; }
#define luai_hashnum(i,n) \
{ volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \
(i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */
#define lua_number2int(i,n) lua_number2int32(i, n, int)
#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned)
/* the trick can be expanded to lua_Integer when it is a 32-bit value */
#if defined(LUA_IEEELL)
#define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer)
#endif
#endif /* } */
/* the following definitions always work, but may be slow */
#if !defined(lua_number2int)
#define lua_number2int(i,n) ((i)=(int)(n))
#endif
#if !defined(lua_number2integer)
#define lua_number2integer(i,n) ((i)=(lua_Integer)(n))
#endif
#if !defined(lua_number2unsigned) /* { */
/* the following definition assures proper modulo behavior */
#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT)
#include <math.h>
#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1)
#define lua_number2unsigned(i,n) \
((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED))
#else
#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n))
#endif
#endif /* } */
#if !defined(lua_unsigned2number)
/* on several machines, coercion from unsigned to double is slow,
so it may be worth to avoid */
#define lua_unsigned2number(u) \
(((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u))
#endif
#if defined(ltable_c) && !defined(luai_hashnum)
#include <float.h>
#include <math.h>
#define luai_hashnum(i,n) { int e; \
n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \
lua_number2int(i, n); i += e; }
#endif
/*
** macro to control inclusion of some hard tests on stack reallocation
*/
#if !defined(HARDSTACKTESTS)
#define condmovestack(L) ((void)0)
#else
/* realloc stack keeping its size */
#define condmovestack(L) luaD_reallocstack((L), (L)->stacksize)
#endif
#if !defined(HARDMEMTESTS)
#define condchangemem(L) condmovestack(L)
#else
#define condchangemem(L) \
((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1)))
#endif
#endif

279
vendor/lite/src/lib/lua52/lmathlib.c vendored Normal file
View file

@ -0,0 +1,279 @@
/*
** $Id: lmathlib.c,v 1.83.1.1 2013/04/12 18:48:47 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
#include <stdlib.h>
#include <math.h>
#define lmathlib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#undef PI
#define PI ((lua_Number)(3.1415926535897932384626433832795))
#define RADIANS_PER_DEGREE ((lua_Number)(PI/180.0))
static int math_abs (lua_State *L) {
lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
return 1;
}
static int math_sin (lua_State *L) {
lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1)));
return 1;
}
static int math_sinh (lua_State *L) {
lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_cos (lua_State *L) {
lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1)));
return 1;
}
static int math_cosh (lua_State *L) {
lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_tan (lua_State *L) {
lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1)));
return 1;
}
static int math_tanh (lua_State *L) {
lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1)));
return 1;
}
static int math_asin (lua_State *L) {
lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1)));
return 1;
}
static int math_acos (lua_State *L) {
lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1)));
return 1;
}
static int math_atan (lua_State *L) {
lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1)));
return 1;
}
static int math_atan2 (lua_State *L) {
lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1),
luaL_checknumber(L, 2)));
return 1;
}
static int math_ceil (lua_State *L) {
lua_pushnumber(L, l_mathop(ceil)(luaL_checknumber(L, 1)));
return 1;
}
static int math_floor (lua_State *L) {
lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1)));
return 1;
}
static int math_fmod (lua_State *L) {
lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
luaL_checknumber(L, 2)));
return 1;
}
static int math_modf (lua_State *L) {
lua_Number ip;
lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip);
lua_pushnumber(L, ip);
lua_pushnumber(L, fp);
return 2;
}
static int math_sqrt (lua_State *L) {
lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
return 1;
}
static int math_pow (lua_State *L) {
lua_Number x = luaL_checknumber(L, 1);
lua_Number y = luaL_checknumber(L, 2);
lua_pushnumber(L, l_mathop(pow)(x, y));
return 1;
}
static int math_log (lua_State *L) {
lua_Number x = luaL_checknumber(L, 1);
lua_Number res;
if (lua_isnoneornil(L, 2))
res = l_mathop(log)(x);
else {
lua_Number base = luaL_checknumber(L, 2);
if (base == (lua_Number)10.0) res = l_mathop(log10)(x);
else res = l_mathop(log)(x)/l_mathop(log)(base);
}
lua_pushnumber(L, res);
return 1;
}
#if defined(LUA_COMPAT_LOG10)
static int math_log10 (lua_State *L) {
lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1)));
return 1;
}
#endif
static int math_exp (lua_State *L) {
lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1)));
return 1;
}
static int math_deg (lua_State *L) {
lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
return 1;
}
static int math_rad (lua_State *L) {
lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
return 1;
}
static int math_frexp (lua_State *L) {
int e;
lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e));
lua_pushinteger(L, e);
return 2;
}
static int math_ldexp (lua_State *L) {
lua_Number x = luaL_checknumber(L, 1);
int ep = luaL_checkint(L, 2);
lua_pushnumber(L, l_mathop(ldexp)(x, ep));
return 1;
}
static int math_min (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
lua_Number dmin = luaL_checknumber(L, 1);
int i;
for (i=2; i<=n; i++) {
lua_Number d = luaL_checknumber(L, i);
if (d < dmin)
dmin = d;
}
lua_pushnumber(L, dmin);
return 1;
}
static int math_max (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
lua_Number dmax = luaL_checknumber(L, 1);
int i;
for (i=2; i<=n; i++) {
lua_Number d = luaL_checknumber(L, i);
if (d > dmax)
dmax = d;
}
lua_pushnumber(L, dmax);
return 1;
}
static int math_random (lua_State *L) {
/* the `%' avoids the (rare) case of r==1, and is needed also because on
some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
switch (lua_gettop(L)) { /* check number of arguments */
case 0: { /* no arguments */
lua_pushnumber(L, r); /* Number between 0 and 1 */
break;
}
case 1: { /* only upper limit */
lua_Number u = luaL_checknumber(L, 1);
luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty");
lua_pushnumber(L, l_mathop(floor)(r*u) + (lua_Number)(1.0)); /* [1, u] */
break;
}
case 2: { /* lower and upper limits */
lua_Number l = luaL_checknumber(L, 1);
lua_Number u = luaL_checknumber(L, 2);
luaL_argcheck(L, l <= u, 2, "interval is empty");
lua_pushnumber(L, l_mathop(floor)(r*(u-l+1)) + l); /* [l, u] */
break;
}
default: return luaL_error(L, "wrong number of arguments");
}
return 1;
}
static int math_randomseed (lua_State *L) {
srand(luaL_checkunsigned(L, 1));
(void)rand(); /* discard first value to avoid undesirable correlations */
return 0;
}
static const luaL_Reg mathlib[] = {
{"abs", math_abs},
{"acos", math_acos},
{"asin", math_asin},
{"atan2", math_atan2},
{"atan", math_atan},
{"ceil", math_ceil},
{"cosh", math_cosh},
{"cos", math_cos},
{"deg", math_deg},
{"exp", math_exp},
{"floor", math_floor},
{"fmod", math_fmod},
{"frexp", math_frexp},
{"ldexp", math_ldexp},
#if defined(LUA_COMPAT_LOG10)
{"log10", math_log10},
#endif
{"log", math_log},
{"max", math_max},
{"min", math_min},
{"modf", math_modf},
{"pow", math_pow},
{"rad", math_rad},
{"random", math_random},
{"randomseed", math_randomseed},
{"sinh", math_sinh},
{"sin", math_sin},
{"sqrt", math_sqrt},
{"tanh", math_tanh},
{"tan", math_tan},
{NULL, NULL}
};
/*
** Open math library
*/
LUAMOD_API int luaopen_math (lua_State *L) {
luaL_newlib(L, mathlib);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
lua_pushnumber(L, HUGE_VAL);
lua_setfield(L, -2, "huge");
return 1;
}

99
vendor/lite/src/lib/lua52/lmem.c vendored Normal file
View file

@ -0,0 +1,99 @@
/*
** $Id: lmem.c,v 1.84.1.1 2013/04/12 18:48:47 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
#include <stddef.h>
#define lmem_c
#define LUA_CORE
#include "lua.h"
#include "ldebug.h"
#include "ldo.h"
#include "lgc.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
/*
** About the realloc function:
** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
** (`osize' is the old size, `nsize' is the new size)
**
** * frealloc(ud, NULL, x, s) creates a new block of size `s' (no
** matter 'x').
**
** * frealloc(ud, p, x, 0) frees the block `p'
** (in this specific case, frealloc must return NULL);
** particularly, frealloc(ud, NULL, 0, 0) does nothing
** (which is equivalent to free(NULL) in ANSI C)
**
** frealloc returns NULL if it cannot create or reallocate the area
** (any reallocation to an equal or smaller size cannot fail!)
*/
#define MINSIZEARRAY 4
void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
int limit, const char *what) {
void *newblock;
int newsize;
if (*size >= limit/2) { /* cannot double it? */
if (*size >= limit) /* cannot grow even a little? */
luaG_runerror(L, "too many %s (limit is %d)", what, limit);
newsize = limit; /* still have at least one free place */
}
else {
newsize = (*size)*2;
if (newsize < MINSIZEARRAY)
newsize = MINSIZEARRAY; /* minimum size */
}
newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
*size = newsize; /* update only when everything else is OK */
return newblock;
}
l_noret luaM_toobig (lua_State *L) {
luaG_runerror(L, "memory allocation error: block too big");
}
/*
** generic allocation routine.
*/
void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
void *newblock;
global_State *g = G(L);
size_t realosize = (block) ? osize : 0;
lua_assert((realosize == 0) == (block == NULL));
#if defined(HARDMEMTESTS)
if (nsize > realosize && g->gcrunning)
luaC_fullgc(L, 1); /* force a GC whenever possible */
#endif
newblock = (*g->frealloc)(g->ud, block, osize, nsize);
if (newblock == NULL && nsize > 0) {
api_check(L, nsize > realosize,
"realloc cannot fail when shrinking a block");
if (g->gcrunning) {
luaC_fullgc(L, 1); /* try to free some memory... */
newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
}
if (newblock == NULL)
luaD_throw(L, LUA_ERRMEM);
}
lua_assert((nsize == 0) == (newblock == NULL));
g->GCdebt = (g->GCdebt + nsize) - realosize;
return newblock;
}

57
vendor/lite/src/lib/lua52/lmem.h vendored Normal file
View file

@ -0,0 +1,57 @@
/*
** $Id: lmem.h,v 1.40.1.1 2013/04/12 18:48:47 roberto Exp $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
#ifndef lmem_h
#define lmem_h
#include <stddef.h>
#include "llimits.h"
#include "lua.h"
/*
** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is
** always constant.
** The macro is somewhat complex to avoid warnings:
** +1 avoids warnings of "comparison has constant result";
** cast to 'void' avoids warnings of "value unused".
*/
#define luaM_reallocv(L,b,on,n,e) \
(cast(void, \
(cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \
luaM_realloc_(L, (b), (on)*(e), (n)*(e)))
#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
#define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0]))
#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s))
#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
#define luaM_newvector(L,n,t) \
cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))
#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s))
#define luaM_growvector(L,v,nelems,size,t,limit,e) \
if ((nelems)+1 > (size)) \
((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e)))
#define luaM_reallocvector(L, v,oldn,n,t) \
((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
LUAI_FUNC l_noret luaM_toobig (lua_State *L);
/* not to be called directly */
LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
size_t size);
LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
size_t size_elem, int limit,
const char *what);
#endif

725
vendor/lite/src/lib/lua52/loadlib.c vendored Normal file
View file

@ -0,0 +1,725 @@
/*
** $Id: loadlib.c,v 1.111.1.1 2013/04/12 18:48:47 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
** This module contains an implementation of loadlib for Unix systems
** that have dlfcn, an implementation for Windows, and a stub for other
** systems.
*/
/*
** if needed, includes windows header before everything else
*/
#if defined(_WIN32)
#include <windows.h>
#endif
#include <stdlib.h>
#include <string.h>
#define loadlib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** LUA_PATH and LUA_CPATH are the names of the environment
** variables that Lua check to set its paths.
*/
#if !defined(LUA_PATH)
#define LUA_PATH "LUA_PATH"
#endif
#if !defined(LUA_CPATH)
#define LUA_CPATH "LUA_CPATH"
#endif
#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
#define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX
#define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
** LUA_IGMARK is a mark to ignore all before it when building the
** luaopen_ function name.
*/
#if !defined (LUA_PATH_SEP)
#define LUA_PATH_SEP ";"
#endif
#if !defined (LUA_PATH_MARK)
#define LUA_PATH_MARK "?"
#endif
#if !defined (LUA_EXEC_DIR)
#define LUA_EXEC_DIR "!"
#endif
#if !defined (LUA_IGMARK)
#define LUA_IGMARK "-"
#endif
/*
** LUA_CSUBSEP is the character that replaces dots in submodule names
** when searching for a C loader.
** LUA_LSUBSEP is the character that replaces dots in submodule names
** when searching for a Lua loader.
*/
#if !defined(LUA_CSUBSEP)
#define LUA_CSUBSEP LUA_DIRSEP
#endif
#if !defined(LUA_LSUBSEP)
#define LUA_LSUBSEP LUA_DIRSEP
#endif
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
/* separator for open functions in C libraries */
#define LUA_OFSEP "_"
/* table (in the registry) that keeps handles for all loaded C libraries */
#define CLIBS "_CLIBS"
#define LIB_FAIL "open"
/* error codes for ll_loadfunc */
#define ERRLIB 1
#define ERRFUNC 2
#define setprogdir(L) ((void)0)
/*
** system-dependent functions
*/
static void ll_unloadlib (void *lib);
static void *ll_load (lua_State *L, const char *path, int seeglb);
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
#if defined(LUA_USE_DLOPEN)
/*
** {========================================================================
** This is an implementation of loadlib based on the dlfcn interface.
** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
** as an emulation layer on top of native functions.
** =========================================================================
*/
#include <dlfcn.h>
static void ll_unloadlib (void *lib) {
dlclose(lib);
}
static void *ll_load (lua_State *L, const char *path, int seeglb) {
void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
if (lib == NULL) lua_pushstring(L, dlerror());
return lib;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
if (f == NULL) lua_pushstring(L, dlerror());
return f;
}
/* }====================================================== */
#elif defined(LUA_DL_DLL)
/*
** {======================================================================
** This is an implementation of loadlib for Windows using native functions.
** =======================================================================
*/
#undef setprogdir
/*
** optional flags for LoadLibraryEx
*/
#if !defined(LUA_LLE_FLAGS)
#define LUA_LLE_FLAGS 0
#endif
static void setprogdir (lua_State *L) {
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize);
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName");
else {
*lb = '\0';
luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
lua_remove(L, -2); /* remove original string */
}
}
static void pusherror (lua_State *L) {
int error = GetLastError();
char buffer[128];
if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL))
lua_pushstring(L, buffer);
else
lua_pushfstring(L, "system error %d\n", error);
}
static void ll_unloadlib (void *lib) {
FreeLibrary((HMODULE)lib);
}
static void *ll_load (lua_State *L, const char *path, int seeglb) {
HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
(void)(seeglb); /* not used: symbols are 'global' by default */
if (lib == NULL) pusherror(L);
return lib;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
if (f == NULL) pusherror(L);
return f;
}
/* }====================================================== */
#else
/*
** {======================================================
** Fallback for other systems
** =======================================================
*/
#undef LIB_FAIL
#define LIB_FAIL "absent"
#define DLMSG "dynamic libraries not enabled; check your Lua installation"
static void ll_unloadlib (void *lib) {
(void)(lib); /* not used */
}
static void *ll_load (lua_State *L, const char *path, int seeglb) {
(void)(path); (void)(seeglb); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
(void)(lib); (void)(sym); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
}
/* }====================================================== */
#endif
static void *ll_checkclib (lua_State *L, const char *path) {
void *plib;
lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
lua_getfield(L, -1, path);
plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */
lua_pop(L, 2); /* pop CLIBS table and 'plib' */
return plib;
}
static void ll_addtoclib (lua_State *L, const char *path, void *plib) {
lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
lua_pushlightuserdata(L, plib);
lua_pushvalue(L, -1);
lua_setfield(L, -3, path); /* CLIBS[path] = plib */
lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */
lua_pop(L, 1); /* pop CLIBS table */
}
/*
** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib
** handles in list CLIBS
*/
static int gctm (lua_State *L) {
int n = luaL_len(L, 1);
for (; n >= 1; n--) { /* for each handle, in reverse order */
lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
ll_unloadlib(lua_touserdata(L, -1));
lua_pop(L, 1); /* pop handle */
}
return 0;
}
static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
void *reg = ll_checkclib(L, path); /* check loaded C libraries */
if (reg == NULL) { /* must load library? */
reg = ll_load(L, path, *sym == '*');
if (reg == NULL) return ERRLIB; /* unable to load library */
ll_addtoclib(L, path, reg);
}
if (*sym == '*') { /* loading only library (no function)? */
lua_pushboolean(L, 1); /* return 'true' */
return 0; /* no errors */
}
else {
lua_CFunction f = ll_sym(L, reg, sym);
if (f == NULL)
return ERRFUNC; /* unable to find function */
lua_pushcfunction(L, f); /* else create new function */
return 0; /* no errors */
}
}
static int ll_loadlib (lua_State *L) {
const char *path = luaL_checkstring(L, 1);
const char *init = luaL_checkstring(L, 2);
int stat = ll_loadfunc(L, path, init);
if (stat == 0) /* no errors? */
return 1; /* return the loaded function */
else { /* error; error message is on stack top */
lua_pushnil(L);
lua_insert(L, -2);
lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
return 3; /* return nil, error message, and where */
}
}
/*
** {======================================================
** 'require' function
** =======================================================
*/
static int readable (const char *filename) {
FILE *f = fopen(filename, "r"); /* try to open file */
if (f == NULL) return 0; /* open failed */
fclose(f);
return 1;
}
static const char *pushnexttemplate (lua_State *L, const char *path) {
const char *l;
while (*path == *LUA_PATH_SEP) path++; /* skip separators */
if (*path == '\0') return NULL; /* no more templates */
l = strchr(path, *LUA_PATH_SEP); /* find next separator */
if (l == NULL) l = path + strlen(path);
lua_pushlstring(L, path, l - path); /* template */
return l;
}
static const char *searchpath (lua_State *L, const char *name,
const char *path,
const char *sep,
const char *dirsep) {
luaL_Buffer msg; /* to build error message */
luaL_buffinit(L, &msg);
if (*sep != '\0') /* non-empty separator? */
name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
while ((path = pushnexttemplate(L, path)) != NULL) {
const char *filename = luaL_gsub(L, lua_tostring(L, -1),
LUA_PATH_MARK, name);
lua_remove(L, -2); /* remove path template */
if (readable(filename)) /* does file exist and is readable? */
return filename; /* return that file name */
lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
lua_remove(L, -2); /* remove file name */
luaL_addvalue(&msg); /* concatenate error msg. entry */
}
luaL_pushresult(&msg); /* create error message */
return NULL; /* not found */
}
static int ll_searchpath (lua_State *L) {
const char *f = searchpath(L, luaL_checkstring(L, 1),
luaL_checkstring(L, 2),
luaL_optstring(L, 3, "."),
luaL_optstring(L, 4, LUA_DIRSEP));
if (f != NULL) return 1;
else { /* error message is on top of the stack */
lua_pushnil(L);
lua_insert(L, -2);
return 2; /* return nil + error message */
}
}
static const char *findfile (lua_State *L, const char *name,
const char *pname,
const char *dirsep) {
const char *path;
lua_getfield(L, lua_upvalueindex(1), pname);
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
return searchpath(L, name, path, ".", dirsep);
}
static int checkload (lua_State *L, int stat, const char *filename) {
if (stat) { /* module loaded successfully? */
lua_pushstring(L, filename); /* will be 2nd argument to module */
return 2; /* return open function and file name */
}
else
return luaL_error(L, "error loading module " LUA_QS
" from file " LUA_QS ":\n\t%s",
lua_tostring(L, 1), filename, lua_tostring(L, -1));
}
static int searcher_Lua (lua_State *L) {
const char *filename;
const char *name = luaL_checkstring(L, 1);
filename = findfile(L, name, "path", LUA_LSUBSEP);
if (filename == NULL) return 1; /* module not found in this path */
return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
}
static int loadfunc (lua_State *L, const char *filename, const char *modname) {
const char *funcname;
const char *mark;
modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
mark = strchr(modname, *LUA_IGMARK);
if (mark) {
int stat;
funcname = lua_pushlstring(L, modname, mark - modname);
funcname = lua_pushfstring(L, LUA_POF"%s", funcname);
stat = ll_loadfunc(L, filename, funcname);
if (stat != ERRFUNC) return stat;
modname = mark + 1; /* else go ahead and try old-style name */
}
funcname = lua_pushfstring(L, LUA_POF"%s", modname);
return ll_loadfunc(L, filename, funcname);
}
static int searcher_C (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
if (filename == NULL) return 1; /* module not found in this path */
return checkload(L, (loadfunc(L, filename, name) == 0), filename);
}
static int searcher_Croot (lua_State *L) {
const char *filename;
const char *name = luaL_checkstring(L, 1);
const char *p = strchr(name, '.');
int stat;
if (p == NULL) return 0; /* is root */
lua_pushlstring(L, name, p - name);
filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
if (filename == NULL) return 1; /* root not found */
if ((stat = loadfunc(L, filename, name)) != 0) {
if (stat != ERRFUNC)
return checkload(L, 0, filename); /* real error */
else { /* open function not found */
lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
name, filename);
return 1;
}
}
lua_pushstring(L, filename); /* will be 2nd argument to module */
return 2;
}
static int searcher_preload (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
lua_getfield(L, -1, name);
if (lua_isnil(L, -1)) /* not found? */
lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
return 1;
}
static void findloader (lua_State *L, const char *name) {
int i;
luaL_Buffer msg; /* to build error message */
luaL_buffinit(L, &msg);
lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
if (!lua_istable(L, 3))
luaL_error(L, LUA_QL("package.searchers") " must be a table");
/* iterate over available searchers to find a loader */
for (i = 1; ; i++) {
lua_rawgeti(L, 3, i); /* get a searcher */
if (lua_isnil(L, -1)) { /* no more searchers? */
lua_pop(L, 1); /* remove nil */
luaL_pushresult(&msg); /* create error message */
luaL_error(L, "module " LUA_QS " not found:%s",
name, lua_tostring(L, -1));
}
lua_pushstring(L, name);
lua_call(L, 1, 2); /* call it */
if (lua_isfunction(L, -2)) /* did it find a loader? */
return; /* module loader found */
else if (lua_isstring(L, -2)) { /* searcher returned error message? */
lua_pop(L, 1); /* remove extra return */
luaL_addvalue(&msg); /* concatenate error message */
}
else
lua_pop(L, 2); /* remove both returns */
}
}
static int ll_require (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
lua_settop(L, 1); /* _LOADED table will be at index 2 */
lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
lua_getfield(L, 2, name); /* _LOADED[name] */
if (lua_toboolean(L, -1)) /* is it there? */
return 1; /* package is already loaded */
/* else must load package */
lua_pop(L, 1); /* remove 'getfield' result */
findloader(L, name);
lua_pushstring(L, name); /* pass name as argument to module loader */
lua_insert(L, -2); /* name is 1st argument (before search data) */
lua_call(L, 2, 1); /* run loader to load module */
if (!lua_isnil(L, -1)) /* non-nil return? */
lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
lua_getfield(L, 2, name);
if (lua_isnil(L, -1)) { /* module did not set a value? */
lua_pushboolean(L, 1); /* use true as result */
lua_pushvalue(L, -1); /* extra copy to be returned */
lua_setfield(L, 2, name); /* _LOADED[name] = true */
}
return 1;
}
/* }====================================================== */
/*
** {======================================================
** 'module' function
** =======================================================
*/
#if defined(LUA_COMPAT_MODULE)
/*
** changes the environment variable of calling function
*/
static void set_env (lua_State *L) {
lua_Debug ar;
if (lua_getstack(L, 1, &ar) == 0 ||
lua_getinfo(L, "f", &ar) == 0 || /* get calling function */
lua_iscfunction(L, -1))
luaL_error(L, LUA_QL("module") " not called from a Lua function");
lua_pushvalue(L, -2); /* copy new environment table to top */
lua_setupvalue(L, -2, 1);
lua_pop(L, 1); /* remove function */
}
static void dooptions (lua_State *L, int n) {
int i;
for (i = 2; i <= n; i++) {
if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */
lua_pushvalue(L, i); /* get option (a function) */
lua_pushvalue(L, -2); /* module */
lua_call(L, 1, 0);
}
}
}
static void modinit (lua_State *L, const char *modname) {
const char *dot;
lua_pushvalue(L, -1);
lua_setfield(L, -2, "_M"); /* module._M = module */
lua_pushstring(L, modname);
lua_setfield(L, -2, "_NAME");
dot = strrchr(modname, '.'); /* look for last dot in module name */
if (dot == NULL) dot = modname;
else dot++;
/* set _PACKAGE as package name (full module name minus last part) */
lua_pushlstring(L, modname, dot - modname);
lua_setfield(L, -2, "_PACKAGE");
}
static int ll_module (lua_State *L) {
const char *modname = luaL_checkstring(L, 1);
int lastarg = lua_gettop(L); /* last parameter */
luaL_pushmodule(L, modname, 1); /* get/create module table */
/* check whether table already has a _NAME field */
lua_getfield(L, -1, "_NAME");
if (!lua_isnil(L, -1)) /* is table an initialized module? */
lua_pop(L, 1);
else { /* no; initialize it */
lua_pop(L, 1);
modinit(L, modname);
}
lua_pushvalue(L, -1);
set_env(L);
dooptions(L, lastarg);
return 1;
}
static int ll_seeall (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
if (!lua_getmetatable(L, 1)) {
lua_createtable(L, 0, 1); /* create new metatable */
lua_pushvalue(L, -1);
lua_setmetatable(L, 1);
}
lua_pushglobaltable(L);
lua_setfield(L, -2, "__index"); /* mt.__index = _G */
return 0;
}
#endif
/* }====================================================== */
/* auxiliary mark (for internal use) */
#define AUXMARK "\1"
/*
** return registry.LUA_NOENV as a boolean
*/
static int noenv (lua_State *L) {
int b;
lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
b = lua_toboolean(L, -1);
lua_pop(L, 1); /* remove value */
return b;
}
static void setpath (lua_State *L, const char *fieldname, const char *envname1,
const char *envname2, const char *def) {
const char *path = getenv(envname1);
if (path == NULL) /* no environment variable? */
path = getenv(envname2); /* try alternative name */
if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, def); /* use default */
else {
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
luaL_gsub(L, path, AUXMARK, def);
lua_remove(L, -2);
}
setprogdir(L);
lua_setfield(L, -2, fieldname);
}
static const luaL_Reg pk_funcs[] = {
{"loadlib", ll_loadlib},
{"searchpath", ll_searchpath},
#if defined(LUA_COMPAT_MODULE)
{"seeall", ll_seeall},
#endif
{NULL, NULL}
};
static const luaL_Reg ll_funcs[] = {
#if defined(LUA_COMPAT_MODULE)
{"module", ll_module},
#endif
{"require", ll_require},
{NULL, NULL}
};
static void createsearcherstable (lua_State *L) {
static const lua_CFunction searchers[] =
{searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
int i;
/* create 'searchers' table */
lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
/* fill it with pre-defined searchers */
for (i=0; searchers[i] != NULL; i++) {
lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */
lua_pushcclosure(L, searchers[i], 1);
lua_rawseti(L, -2, i+1);
}
}
LUAMOD_API int luaopen_package (lua_State *L) {
/* create table CLIBS to keep track of loaded C libraries */
luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS);
lua_createtable(L, 0, 1); /* metatable for CLIBS */
lua_pushcfunction(L, gctm);
lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
lua_setmetatable(L, -2);
/* create `package' table */
luaL_newlib(L, pk_funcs);
createsearcherstable(L);
#if defined(LUA_COMPAT_LOADERS)
lua_pushvalue(L, -1); /* make a copy of 'searchers' table */
lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */
#endif
lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
/* set field 'path' */
setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT);
/* set field 'cpath' */
setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT);
/* store config information */
lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
lua_setfield(L, -2, "config");
/* set field `loaded' */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
lua_setfield(L, -2, "loaded");
/* set field `preload' */
luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
lua_setfield(L, -2, "preload");
lua_pushglobaltable(L);
lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */
luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */
lua_pop(L, 1); /* pop global table */
return 1; /* return 'package' table */
}

287
vendor/lite/src/lib/lua52/lobject.c vendored Normal file
View file

@ -0,0 +1,287 @@
/*
** $Id: lobject.c,v 2.58.1.1 2013/04/12 18:48:47 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define lobject_c
#define LUA_CORE
#include "lua.h"
#include "lctype.h"
#include "ldebug.h"
#include "ldo.h"
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "lvm.h"
LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT};
/*
** converts an integer to a "floating point byte", represented as
** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
** eeeee != 0 and (xxx) otherwise.
*/
int luaO_int2fb (unsigned int x) {
int e = 0; /* exponent */
if (x < 8) return x;
while (x >= 0x10) {
x = (x+1) >> 1;
e++;
}
return ((e+1) << 3) | (cast_int(x) - 8);
}
/* converts back */
int luaO_fb2int (int x) {
int e = (x >> 3) & 0x1f;
if (e == 0) return x;
else return ((x & 7) + 8) << (e - 1);
}
int luaO_ceillog2 (unsigned int x) {
static const lu_byte log_2[256] = {
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
};
int l = 0;
x--;
while (x >= 256) { l += 8; x >>= 8; }
return l + log_2[x];
}
lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
switch (op) {
case LUA_OPADD: return luai_numadd(NULL, v1, v2);
case LUA_OPSUB: return luai_numsub(NULL, v1, v2);
case LUA_OPMUL: return luai_nummul(NULL, v1, v2);
case LUA_OPDIV: return luai_numdiv(NULL, v1, v2);
case LUA_OPMOD: return luai_nummod(NULL, v1, v2);
case LUA_OPPOW: return luai_numpow(NULL, v1, v2);
case LUA_OPUNM: return luai_numunm(NULL, v1);
default: lua_assert(0); return 0;
}
}
int luaO_hexavalue (int c) {
if (lisdigit(c)) return c - '0';
else return ltolower(c) - 'a' + 10;
}
#if !defined(lua_strx2number)
#include <math.h>
static int isneg (const char **s) {
if (**s == '-') { (*s)++; return 1; }
else if (**s == '+') (*s)++;
return 0;
}
static lua_Number readhexa (const char **s, lua_Number r, int *count) {
for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */
r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s)));
(*count)++;
}
return r;
}
/*
** convert an hexadecimal numeric string to a number, following
** C99 specification for 'strtod'
*/
static lua_Number lua_strx2number (const char *s, char **endptr) {
lua_Number r = 0.0;
int e = 0, i = 0;
int neg = 0; /* 1 if number is negative */
*endptr = cast(char *, s); /* nothing is valid yet */
while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
neg = isneg(&s); /* check signal */
if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
return 0.0; /* invalid format (no '0x') */
s += 2; /* skip '0x' */
r = readhexa(&s, r, &i); /* read integer part */
if (*s == '.') {
s++; /* skip dot */
r = readhexa(&s, r, &e); /* read fractional part */
}
if (i == 0 && e == 0)
return 0.0; /* invalid format (no digit) */
e *= -4; /* each fractional digit divides value by 2^-4 */
*endptr = cast(char *, s); /* valid up to here */
if (*s == 'p' || *s == 'P') { /* exponent part? */
int exp1 = 0;
int neg1;
s++; /* skip 'p' */
neg1 = isneg(&s); /* signal */
if (!lisdigit(cast_uchar(*s)))
goto ret; /* must have at least one digit */
while (lisdigit(cast_uchar(*s))) /* read exponent */
exp1 = exp1 * 10 + *(s++) - '0';
if (neg1) exp1 = -exp1;
e += exp1;
}
*endptr = cast(char *, s); /* valid up to here */
ret:
if (neg) r = -r;
return l_mathop(ldexp)(r, e);
}
#endif
int luaO_str2d (const char *s, size_t len, lua_Number *result) {
char *endptr;
if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
return 0;
else if (strpbrk(s, "xX")) /* hexa? */
*result = lua_strx2number(s, &endptr);
else
*result = lua_str2number(s, &endptr);
if (endptr == s) return 0; /* nothing recognized */
while (lisspace(cast_uchar(*endptr))) endptr++;
return (endptr == s + len); /* OK if no trailing characters */
}
static void pushstr (lua_State *L, const char *str, size_t l) {
setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
}
/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
int n = 0;
for (;;) {
const char *e = strchr(fmt, '%');
if (e == NULL) break;
luaD_checkstack(L, 2); /* fmt + item */
pushstr(L, fmt, e - fmt);
switch (*(e+1)) {
case 's': {
const char *s = va_arg(argp, char *);
if (s == NULL) s = "(null)";
pushstr(L, s, strlen(s));
break;
}
case 'c': {
char buff;
buff = cast(char, va_arg(argp, int));
pushstr(L, &buff, 1);
break;
}
case 'd': {
setnvalue(L->top++, cast_num(va_arg(argp, int)));
break;
}
case 'f': {
setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber)));
break;
}
case 'p': {
char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
int l = sprintf(buff, "%p", va_arg(argp, void *));
pushstr(L, buff, l);
break;
}
case '%': {
pushstr(L, "%", 1);
break;
}
default: {
luaG_runerror(L,
"invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
*(e + 1));
}
}
n += 2;
fmt = e+2;
}
luaD_checkstack(L, 1);
pushstr(L, fmt, strlen(fmt));
if (n > 0) luaV_concat(L, n + 1);
return svalue(L->top - 1);
}
const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
const char *msg;
va_list argp;
va_start(argp, fmt);
msg = luaO_pushvfstring(L, fmt, argp);
va_end(argp);
return msg;
}
/* number of chars of a literal string without the ending \0 */
#define LL(x) (sizeof(x)/sizeof(char) - 1)
#define RETS "..."
#define PRE "[string \""
#define POS "\"]"
#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
void luaO_chunkid (char *out, const char *source, size_t bufflen) {
size_t l = strlen(source);
if (*source == '=') { /* 'literal' source */
if (l <= bufflen) /* small enough? */
memcpy(out, source + 1, l * sizeof(char));
else { /* truncate it */
addstr(out, source + 1, bufflen - 1);
*out = '\0';
}
}
else if (*source == '@') { /* file name */
if (l <= bufflen) /* small enough? */
memcpy(out, source + 1, l * sizeof(char));
else { /* add '...' before rest of name */
addstr(out, RETS, LL(RETS));
bufflen -= LL(RETS);
memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
}
}
else { /* string; format as [string "source"] */
const char *nl = strchr(source, '\n'); /* find first new line (if any) */
addstr(out, PRE, LL(PRE)); /* add prefix */
bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
if (l < bufflen && nl == NULL) { /* small one-line source? */
addstr(out, source, l); /* keep it */
}
else {
if (nl != NULL) l = nl - source; /* stop at first newline */
if (l > bufflen) l = bufflen;
addstr(out, source, l);
addstr(out, RETS, LL(RETS));
}
memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
}
}

607
vendor/lite/src/lib/lua52/lobject.h vendored Normal file
View file

@ -0,0 +1,607 @@
/*
** $Id: lobject.h,v 2.71.1.2 2014/05/07 14:14:58 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
#ifndef lobject_h
#define lobject_h
#include <stdarg.h>
#include "llimits.h"
#include "lua.h"
/*
** Extra tags for non-values
*/
#define LUA_TPROTO LUA_NUMTAGS
#define LUA_TUPVAL (LUA_NUMTAGS+1)
#define LUA_TDEADKEY (LUA_NUMTAGS+2)
/*
** number of all possible tags (including LUA_TNONE but excluding DEADKEY)
*/
#define LUA_TOTALTAGS (LUA_TUPVAL+2)
/*
** tags for Tagged Values have the following use of bits:
** bits 0-3: actual tag (a LUA_T* value)
** bits 4-5: variant bits
** bit 6: whether value is collectable
*/
#define VARBITS (3 << 4)
/*
** LUA_TFUNCTION variants:
** 0 - Lua function
** 1 - light C function
** 2 - regular C function (closure)
*/
/* Variant tags for functions */
#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */
#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */
#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */
/* Variant tags for strings */
#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */
#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */
/* Bit mark for collectable types */
#define BIT_ISCOLLECTABLE (1 << 6)
/* mark a tag as collectable */
#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
/*
** Union of all collectable objects
*/
typedef union GCObject GCObject;
/*
** Common Header for all collectable objects (in macro form, to be
** included in other objects)
*/
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
/*
** Common header in struct form
*/
typedef struct GCheader {
CommonHeader;
} GCheader;
/*
** Union of all Lua values
*/
typedef union Value Value;
#define numfield lua_Number n; /* numbers */
/*
** Tagged Values. This is the basic representation of values in Lua,
** an actual value plus a tag with its type.
*/
#define TValuefields Value value_; int tt_
typedef struct lua_TValue TValue;
/* macro defining a nil value */
#define NILCONSTANT {NULL}, LUA_TNIL
#define val_(o) ((o)->value_)
#define num_(o) (val_(o).n)
/* raw type tag of a TValue */
#define rttype(o) ((o)->tt_)
/* tag with no variants (bits 0-3) */
#define novariant(x) ((x) & 0x0F)
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
#define ttype(o) (rttype(o) & 0x3F)
/* type tag of a TValue with no variants (bits 0-3) */
#define ttypenv(o) (novariant(rttype(o)))
/* Macros to test type */
#define checktag(o,t) (rttype(o) == (t))
#define checktype(o,t) (ttypenv(o) == (t))
#define ttisnumber(o) checktag((o), LUA_TNUMBER)
#define ttisnil(o) checktag((o), LUA_TNIL)
#define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
#define ttisstring(o) checktype((o), LUA_TSTRING)
#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR))
#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR))
#define ttistable(o) checktag((o), ctb(LUA_TTABLE))
#define ttisfunction(o) checktype(o, LUA_TFUNCTION)
#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
#define ttislcf(o) checktag((o), LUA_TLCF)
#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA))
#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
#define ttisequal(o1,o2) (rttype(o1) == rttype(o2))
/* Macros to access values */
#define nvalue(o) check_exp(ttisnumber(o), num_(o))
#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts)
#define tsvalue(o) (&rawtsvalue(o)->tsv)
#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u)
#define uvalue(o) (&rawuvalue(o)->uv)
#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl)
#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l)
#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c)
#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h)
#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
#define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th)
/* a dead value may get the 'gc' field, but cannot access its contents */
#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
/* Macros for internal tests */
#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt)
#define checkliveness(g,obj) \
lua_longassert(!iscollectable(obj) || \
(righttt(obj) && !isdead(g,gcvalue(obj))))
/* Macros to set values */
#define settt_(o,t) ((o)->tt_=(t))
#define setnvalue(obj,x) \
{ TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); }
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
#define setfvalue(obj,x) \
{ TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }
#define setpvalue(obj,x) \
{ TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }
#define setbvalue(obj,x) \
{ TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }
#define setgcovalue(L,obj,x) \
{ TValue *io=(obj); GCObject *i_g=(x); \
val_(io).gc=i_g; settt_(io, ctb(gch(i_g)->tt)); }
#define setsvalue(L,obj,x) \
{ TValue *io=(obj); \
TString *x_ = (x); \
val_(io).gc=cast(GCObject *, x_); settt_(io, ctb(x_->tsv.tt)); \
checkliveness(G(L),io); }
#define setuvalue(L,obj,x) \
{ TValue *io=(obj); \
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \
checkliveness(G(L),io); }
#define setthvalue(L,obj,x) \
{ TValue *io=(obj); \
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \
checkliveness(G(L),io); }
#define setclLvalue(L,obj,x) \
{ TValue *io=(obj); \
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \
checkliveness(G(L),io); }
#define setclCvalue(L,obj,x) \
{ TValue *io=(obj); \
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \
checkliveness(G(L),io); }
#define sethvalue(L,obj,x) \
{ TValue *io=(obj); \
val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \
checkliveness(G(L),io); }
#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
#define setobj(L,obj1,obj2) \
{ const TValue *io2=(obj2); TValue *io1=(obj1); \
io1->value_ = io2->value_; io1->tt_ = io2->tt_; \
checkliveness(G(L),io1); }
/*
** different types of assignments, according to destination
*/
/* from stack to (same) stack */
#define setobjs2s setobj
/* to stack (not from same stack) */
#define setobj2s setobj
#define setsvalue2s setsvalue
#define sethvalue2s sethvalue
#define setptvalue2s setptvalue
/* from table to same table */
#define setobjt2t setobj
/* to table */
#define setobj2t setobj
/* to new object */
#define setobj2n setobj
#define setsvalue2n setsvalue
/* check whether a number is valid (useful only for NaN trick) */
#define luai_checknum(L,o,c) { /* empty */ }
/*
** {======================================================
** NaN Trick
** =======================================================
*/
#if defined(LUA_NANTRICK)
/*
** numbers are represented in the 'd_' field. All other values have the
** value (NNMARK | tag) in 'tt__'. A number with such pattern would be
** a "signaled NaN", which is never generated by regular operations by
** the CPU (nor by 'strtod')
*/
/* allows for external implementation for part of the trick */
#if !defined(NNMARK) /* { */
#if !defined(LUA_IEEEENDIAN)
#error option 'LUA_NANTRICK' needs 'LUA_IEEEENDIAN'
#endif
#define NNMARK 0x7FF7A500
#define NNMASK 0x7FFFFF00
#undef TValuefields
#undef NILCONSTANT
#if (LUA_IEEEENDIAN == 0) /* { */
/* little endian */
#define TValuefields \
union { struct { Value v__; int tt__; } i; double d__; } u
#define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}}
/* field-access macros */
#define v_(o) ((o)->u.i.v__)
#define d_(o) ((o)->u.d__)
#define tt_(o) ((o)->u.i.tt__)
#else /* }{ */
/* big endian */
#define TValuefields \
union { struct { int tt__; Value v__; } i; double d__; } u
#define NILCONSTANT {{tag2tt(LUA_TNIL), {NULL}}}
/* field-access macros */
#define v_(o) ((o)->u.i.v__)
#define d_(o) ((o)->u.d__)
#define tt_(o) ((o)->u.i.tt__)
#endif /* } */
#endif /* } */
/* correspondence with standard representation */
#undef val_
#define val_(o) v_(o)
#undef num_
#define num_(o) d_(o)
#undef numfield
#define numfield /* no such field; numbers are the entire struct */
/* basic check to distinguish numbers from non-numbers */
#undef ttisnumber
#define ttisnumber(o) ((tt_(o) & NNMASK) != NNMARK)
#define tag2tt(t) (NNMARK | (t))
#undef rttype
#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff)
#undef settt_
#define settt_(o,t) (tt_(o) = tag2tt(t))
#undef setnvalue
#define setnvalue(obj,x) \
{ TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); }
#undef setobj
#define setobj(L,obj1,obj2) \
{ const TValue *o2_=(obj2); TValue *o1_=(obj1); \
o1_->u = o2_->u; \
checkliveness(G(L),o1_); }
/*
** these redefinitions are not mandatory, but these forms are more efficient
*/
#undef checktag
#undef checktype
#define checktag(o,t) (tt_(o) == tag2tt(t))
#define checktype(o,t) (ctb(tt_(o) | VARBITS) == ctb(tag2tt(t) | VARBITS))
#undef ttisequal
#define ttisequal(o1,o2) \
(ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2)))
#undef luai_checknum
#define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; }
#endif
/* }====================================================== */
/*
** {======================================================
** types and prototypes
** =======================================================
*/
union Value {
GCObject *gc; /* collectable objects */
void *p; /* light userdata */
int b; /* booleans */
lua_CFunction f; /* light C functions */
numfield /* numbers */
};
struct lua_TValue {
TValuefields;
};
typedef TValue *StkId; /* index to stack elements */
/*
** Header for string value; string bytes follow the end of this structure
*/
typedef union TString {
L_Umaxalign dummy; /* ensures maximum alignment for strings */
struct {
CommonHeader;
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
unsigned int hash;
size_t len; /* number of characters in string */
} tsv;
} TString;
/* get the actual string (array of bytes) from a TString */
#define getstr(ts) cast(const char *, (ts) + 1)
/* get the actual string (array of bytes) from a Lua value */
#define svalue(o) getstr(rawtsvalue(o))
/*
** Header for userdata; memory area follows the end of this structure
*/
typedef union Udata {
L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
struct {
CommonHeader;
struct Table *metatable;
struct Table *env;
size_t len; /* number of bytes */
} uv;
} Udata;
/*
** Description of an upvalue for function prototypes
*/
typedef struct Upvaldesc {
TString *name; /* upvalue name (for debug information) */
lu_byte instack; /* whether it is in stack */
lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
} Upvaldesc;
/*
** Description of a local variable for function prototypes
** (used for debug information)
*/
typedef struct LocVar {
TString *varname;
int startpc; /* first point where variable is active */
int endpc; /* first point where variable is dead */
} LocVar;
/*
** Function Prototypes
*/
typedef struct Proto {
CommonHeader;
TValue *k; /* constants used by the function */
Instruction *code;
struct Proto **p; /* functions defined inside the function */
int *lineinfo; /* map from opcodes to source lines (debug information) */
LocVar *locvars; /* information about local variables (debug information) */
Upvaldesc *upvalues; /* upvalue information */
union Closure *cache; /* last created closure with this prototype */
TString *source; /* used for debug information */
int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of `k' */
int sizecode;
int sizelineinfo;
int sizep; /* size of `p' */
int sizelocvars;
int linedefined;
int lastlinedefined;
GCObject *gclist;
lu_byte numparams; /* number of fixed parameters */
lu_byte is_vararg;
lu_byte maxstacksize; /* maximum stack used by this function */
} Proto;
/*
** Lua Upvalues
*/
typedef struct UpVal {
CommonHeader;
TValue *v; /* points to stack or to its own value */
union {
TValue value; /* the value (when closed) */
struct { /* double linked list (when open) */
struct UpVal *prev;
struct UpVal *next;
} l;
} u;
} UpVal;
/*
** Closures
*/
#define ClosureHeader \
CommonHeader; lu_byte nupvalues; GCObject *gclist
typedef struct CClosure {
ClosureHeader;
lua_CFunction f;
TValue upvalue[1]; /* list of upvalues */
} CClosure;
typedef struct LClosure {
ClosureHeader;
struct Proto *p;
UpVal *upvals[1]; /* list of upvalues */
} LClosure;
typedef union Closure {
CClosure c;
LClosure l;
} Closure;
#define isLfunction(o) ttisLclosure(o)
#define getproto(o) (clLvalue(o)->p)
/*
** Tables
*/
typedef union TKey {
struct {
TValuefields;
struct Node *next; /* for chaining */
} nk;
TValue tvk;
} TKey;
typedef struct Node {
TValue i_val;
TKey i_key;
} Node;
typedef struct Table {
CommonHeader;
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */
int sizearray; /* size of `array' array */
TValue *array; /* array part */
Node *node;
Node *lastfree; /* any free position is before this position */
struct Table *metatable;
GCObject *gclist;
} Table;
/*
** `module' operation for hashing (size is always a power of 2)
*/
#define lmod(s,size) \
(check_exp((size&(size-1))==0, (cast(int, (s) & ((size)-1)))))
#define twoto(x) (1<<(x))
#define sizenode(t) (twoto((t)->lsizenode))
/*
** (address of) a fixed nil value
*/
#define luaO_nilobject (&luaO_nilobject_)
LUAI_DDEC const TValue luaO_nilobject_;
LUAI_FUNC int luaO_int2fb (unsigned int x);
LUAI_FUNC int luaO_fb2int (int x);
LUAI_FUNC int luaO_ceillog2 (unsigned int x);
LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2);
LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result);
LUAI_FUNC int luaO_hexavalue (int c);
LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
va_list argp);
LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
#endif

107
vendor/lite/src/lib/lua52/lopcodes.c vendored Normal file
View file

@ -0,0 +1,107 @@
/*
** $Id: lopcodes.c,v 1.49.1.1 2013/04/12 18:48:47 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
#define lopcodes_c
#define LUA_CORE
#include "lopcodes.h"
/* ORDER OP */
LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
"MOVE",
"LOADK",
"LOADKX",
"LOADBOOL",
"LOADNIL",
"GETUPVAL",
"GETTABUP",
"GETTABLE",
"SETTABUP",
"SETUPVAL",
"SETTABLE",
"NEWTABLE",
"SELF",
"ADD",
"SUB",
"MUL",
"DIV",
"MOD",
"POW",
"UNM",
"NOT",
"LEN",
"CONCAT",
"JMP",
"EQ",
"LT",
"LE",
"TEST",
"TESTSET",
"CALL",
"TAILCALL",
"RETURN",
"FORLOOP",
"FORPREP",
"TFORCALL",
"TFORLOOP",
"SETLIST",
"CLOSURE",
"VARARG",
"EXTRAARG",
NULL
};
#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T A B C mode opcode */
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */
,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */
,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */
};

288
vendor/lite/src/lib/lua52/lopcodes.h vendored Normal file
View file

@ -0,0 +1,288 @@
/*
** $Id: lopcodes.h,v 1.142.1.2 2014/10/20 18:32:09 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
#ifndef lopcodes_h
#define lopcodes_h
#include "llimits.h"
/*===========================================================================
We assume that instructions are unsigned numbers.
All instructions have an opcode in the first 6 bits.
Instructions can have the following fields:
`A' : 8 bits
`B' : 9 bits
`C' : 9 bits
'Ax' : 26 bits ('A', 'B', and 'C' together)
`Bx' : 18 bits (`B' and `C' together)
`sBx' : signed Bx
A signed argument is represented in excess K; that is, the number
value is the unsigned value minus K. K is exactly the maximum value
for that argument (so that -max is represented by 0, and +max is
represented by 2*max), which is half the maximum for the corresponding
unsigned argument.
===========================================================================*/
enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */
/*
** size and position of opcode arguments.
*/
#define SIZE_C 9
#define SIZE_B 9
#define SIZE_Bx (SIZE_C + SIZE_B)
#define SIZE_A 8
#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A)
#define SIZE_OP 6
#define POS_OP 0
#define POS_A (POS_OP + SIZE_OP)
#define POS_C (POS_A + SIZE_A)
#define POS_B (POS_C + SIZE_C)
#define POS_Bx POS_C
#define POS_Ax POS_A
/*
** limits for opcode arguments.
** we use (signed) int to manipulate most arguments,
** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
*/
#if SIZE_Bx < LUAI_BITSINT-1
#define MAXARG_Bx ((1<<SIZE_Bx)-1)
#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */
#else
#define MAXARG_Bx MAX_INT
#define MAXARG_sBx MAX_INT
#endif
#if SIZE_Ax < LUAI_BITSINT-1
#define MAXARG_Ax ((1<<SIZE_Ax)-1)
#else
#define MAXARG_Ax MAX_INT
#endif
#define MAXARG_A ((1<<SIZE_A)-1)
#define MAXARG_B ((1<<SIZE_B)-1)
#define MAXARG_C ((1<<SIZE_C)-1)
/* creates a mask with `n' 1 bits at position `p' */
#define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p))
/* creates a mask with `n' 0 bits at position `p' */
#define MASK0(n,p) (~MASK1(n,p))
/*
** the following macros help to manipulate instructions
*/
#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
((cast(Instruction, o)<<POS_OP)&MASK1(SIZE_OP,POS_OP))))
#define getarg(i,pos,size) (cast(int, ((i)>>pos) & MASK1(size,0)))
#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \
((cast(Instruction, v)<<pos)&MASK1(size,pos))))
#define GETARG_A(i) getarg(i, POS_A, SIZE_A)
#define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A)
#define GETARG_B(i) getarg(i, POS_B, SIZE_B)
#define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B)
#define GETARG_C(i) getarg(i, POS_C, SIZE_C)
#define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C)
#define GETARG_Bx(i) getarg(i, POS_Bx, SIZE_Bx)
#define SETARG_Bx(i,v) setarg(i, v, POS_Bx, SIZE_Bx)
#define GETARG_Ax(i) getarg(i, POS_Ax, SIZE_Ax)
#define SETARG_Ax(i,v) setarg(i, v, POS_Ax, SIZE_Ax)
#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))
#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<<POS_OP) \
| (cast(Instruction, a)<<POS_A) \
| (cast(Instruction, b)<<POS_B) \
| (cast(Instruction, c)<<POS_C))
#define CREATE_ABx(o,a,bc) ((cast(Instruction, o)<<POS_OP) \
| (cast(Instruction, a)<<POS_A) \
| (cast(Instruction, bc)<<POS_Bx))
#define CREATE_Ax(o,a) ((cast(Instruction, o)<<POS_OP) \
| (cast(Instruction, a)<<POS_Ax))
/*
** Macros to operate RK indices
*/
/* this bit 1 means constant (0 means register) */
#define BITRK (1 << (SIZE_B - 1))
/* test whether value is a constant */
#define ISK(x) ((x) & BITRK)
/* gets the index of the constant */
#define INDEXK(r) ((int)(r) & ~BITRK)
#define MAXINDEXRK (BITRK - 1)
/* code a constant index as a RK value */
#define RKASK(x) ((x) | BITRK)
/*
** invalid register that fits in 8 bits
*/
#define NO_REG MAXARG_A
/*
** R(x) - register
** Kst(x) - constant (in constant table)
** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
*/
/*
** grep "ORDER OP" if you change these enums
*/
typedef enum {
/*----------------------------------------------------------------------
name args description
------------------------------------------------------------------------*/
OP_MOVE,/* A B R(A) := R(B) */
OP_LOADK,/* A Bx R(A) := Kst(Bx) */
OP_LOADKX,/* A R(A) := Kst(extra arg) */
OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
OP_LOADNIL,/* A B R(A), R(A+1), ..., R(A+B) := nil */
OP_GETUPVAL,/* A B R(A) := UpValue[B] */
OP_GETTABUP,/* A B C R(A) := UpValue[B][RK(C)] */
OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */
OP_SETTABUP,/* A B C UpValue[A][RK(B)] := RK(C) */
OP_SETUPVAL,/* A B UpValue[B] := R(A) */
OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */
OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */
OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */
OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
OP_UNM,/* A B R(A) := -R(B) */
OP_NOT,/* A B R(A) := not R(B) */
OP_LEN,/* A B R(A) := length of R(B) */
OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */
OP_JMP,/* A sBx pc+=sBx; if (A) close all upvalues >= R(A - 1) */
OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
OP_FORLOOP,/* A sBx R(A)+=R(A+2);
if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */
OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
} OpCode;
#define NUM_OPCODES (cast(int, OP_EXTRAARG) + 1)
/*===========================================================================
Notes:
(*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then `top' is
set to last_result+1, so next open instruction (OP_CALL, OP_RETURN,
OP_SETLIST) may use `top'.
(*) In OP_VARARG, if (B == 0) then use actual number of varargs and
set top (like in OP_CALL with C == 0).
(*) In OP_RETURN, if (B == 0) then return up to `top'.
(*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next
'instruction' is EXTRAARG(real C).
(*) In OP_LOADKX, the next 'instruction' is always EXTRAARG.
(*) For comparisons, A specifies what condition the test should accept
(true or false).
(*) All `skips' (pc++) assume that next instruction is a jump.
===========================================================================*/
/*
** masks for instruction properties. The format is:
** bits 0-1: op mode
** bits 2-3: C arg mode
** bits 4-5: B arg mode
** bit 6: instruction set register A
** bit 7: operator is a test (next instruction must be a jump)
*/
enum OpArgMask {
OpArgN, /* argument is not used */
OpArgU, /* argument is used */
OpArgR, /* argument is a register or a jump offset */
OpArgK /* argument is a constant or register/constant */
};
LUAI_DDEC const lu_byte luaP_opmodes[NUM_OPCODES];
#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
/* number of list items to accumulate before a SETLIST instruction */
#define LFIELDS_PER_FLUSH 50
#endif

323
vendor/lite/src/lib/lua52/loslib.c vendored Normal file
View file

@ -0,0 +1,323 @@
/*
** $Id: loslib.c,v 1.40.1.1 2013/04/12 18:48:47 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
#include <errno.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define loslib_c
#define LUA_LIB
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
/*
** list of valid conversion specifiers for the 'strftime' function
*/
#if !defined(LUA_STRFTIMEOPTIONS)
#if !defined(LUA_USE_POSIX)
#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
#else
#define LUA_STRFTIMEOPTIONS \
{ "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "" \
"", "E", "cCxXyY", \
"O", "deHImMSuUVwWy" }
#endif
#endif
/*
** By default, Lua uses tmpnam except when POSIX is available, where it
** uses mkstemp.
*/
#if defined(LUA_USE_MKSTEMP)
#include <unistd.h>
#define LUA_TMPNAMBUFSIZE 32
#define lua_tmpnam(b,e) { \
strcpy(b, "/tmp/lua_XXXXXX"); \
e = mkstemp(b); \
if (e != -1) close(e); \
e = (e == -1); }
#elif !defined(lua_tmpnam)
#define LUA_TMPNAMBUFSIZE L_tmpnam
#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
#endif
/*
** By default, Lua uses gmtime/localtime, except when POSIX is available,
** where it uses gmtime_r/localtime_r
*/
#if defined(LUA_USE_GMTIME_R)
#define l_gmtime(t,r) gmtime_r(t,r)
#define l_localtime(t,r) localtime_r(t,r)
#elif !defined(l_gmtime)
#define l_gmtime(t,r) ((void)r, gmtime(t))
#define l_localtime(t,r) ((void)r, localtime(t))
#endif
static int os_execute (lua_State *L) {
const char *cmd = luaL_optstring(L, 1, NULL);
int stat = system(cmd);
if (cmd != NULL)
return luaL_execresult(L, stat);
else {
lua_pushboolean(L, stat); /* true if there is a shell */
return 1;
}
}
static int os_remove (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
return luaL_fileresult(L, remove(filename) == 0, filename);
}
static int os_rename (lua_State *L) {
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
}
static int os_tmpname (lua_State *L) {
char buff[LUA_TMPNAMBUFSIZE];
int err;
lua_tmpnam(buff, err);
if (err)
return luaL_error(L, "unable to generate a unique filename");
lua_pushstring(L, buff);
return 1;
}
static int os_getenv (lua_State *L) {
lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
return 1;
}
static int os_clock (lua_State *L) {
lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
return 1;
}
/*
** {======================================================
** Time/Date operations
** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
** wday=%w+1, yday=%j, isdst=? }
** =======================================================
*/
static void setfield (lua_State *L, const char *key, int value) {
lua_pushinteger(L, value);
lua_setfield(L, -2, key);
}
static void setboolfield (lua_State *L, const char *key, int value) {
if (value < 0) /* undefined? */
return; /* does not set field */
lua_pushboolean(L, value);
lua_setfield(L, -2, key);
}
static int getboolfield (lua_State *L, const char *key) {
int res;
lua_getfield(L, -1, key);
res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}
static int getfield (lua_State *L, const char *key, int d) {
int res, isnum;
lua_getfield(L, -1, key);
res = (int)lua_tointegerx(L, -1, &isnum);
if (!isnum) {
if (d < 0)
return luaL_error(L, "field " LUA_QS " missing in date table", key);
res = d;
}
lua_pop(L, 1);
return res;
}
static const char *checkoption (lua_State *L, const char *conv, char *buff) {
static const char *const options[] = LUA_STRFTIMEOPTIONS;
unsigned int i;
for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) {
if (*conv != '\0' && strchr(options[i], *conv) != NULL) {
buff[1] = *conv;
if (*options[i + 1] == '\0') { /* one-char conversion specifier? */
buff[2] = '\0'; /* end buffer */
return conv + 1;
}
else if (*(conv + 1) != '\0' &&
strchr(options[i + 1], *(conv + 1)) != NULL) {
buff[2] = *(conv + 1); /* valid two-char conversion specifier */
buff[3] = '\0'; /* end buffer */
return conv + 2;
}
}
}
luaL_argerror(L, 1,
lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv));
return conv; /* to avoid warnings */
}
static int os_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, "%c");
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
struct tm tmr, *stm;
if (*s == '!') { /* UTC? */
stm = l_gmtime(&t, &tmr);
s++; /* skip `!' */
}
else
stm = l_localtime(&t, &tmr);
if (stm == NULL) /* invalid date? */
lua_pushnil(L);
else if (strcmp(s, "*t") == 0) {
lua_createtable(L, 0, 9); /* 9 = number of fields */
setfield(L, "sec", stm->tm_sec);
setfield(L, "min", stm->tm_min);
setfield(L, "hour", stm->tm_hour);
setfield(L, "day", stm->tm_mday);
setfield(L, "month", stm->tm_mon+1);
setfield(L, "year", stm->tm_year+1900);
setfield(L, "wday", stm->tm_wday+1);
setfield(L, "yday", stm->tm_yday+1);
setboolfield(L, "isdst", stm->tm_isdst);
}
else {
char cc[4];
luaL_Buffer b;
cc[0] = '%';
luaL_buffinit(L, &b);
while (*s) {
if (*s != '%') /* no conversion specifier? */
luaL_addchar(&b, *s++);
else {
size_t reslen;
char buff[200]; /* should be big enough for any conversion result */
s = checkoption(L, s + 1, cc);
reslen = strftime(buff, sizeof(buff), cc, stm);
luaL_addlstring(&b, buff, reslen);
}
}
luaL_pushresult(&b);
}
return 1;
}
static int os_time (lua_State *L) {
time_t t;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = time(NULL); /* get current time */
else {
struct tm ts;
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 1); /* make sure table is at the top */
ts.tm_sec = getfield(L, "sec", 0);
ts.tm_min = getfield(L, "min", 0);
ts.tm_hour = getfield(L, "hour", 12);
ts.tm_mday = getfield(L, "day", -1);
ts.tm_mon = getfield(L, "month", -1) - 1;
ts.tm_year = getfield(L, "year", -1) - 1900;
ts.tm_isdst = getboolfield(L, "isdst");
t = mktime(&ts);
}
if (t == (time_t)(-1))
lua_pushnil(L);
else
lua_pushnumber(L, (lua_Number)t);
return 1;
}
static int os_difftime (lua_State *L) {
lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
(time_t)(luaL_optnumber(L, 2, 0))));
return 1;
}
/* }====================================================== */
static int os_setlocale (lua_State *L) {
static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
LC_NUMERIC, LC_TIME};
static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
"numeric", "time", NULL};
const char *l = luaL_optstring(L, 1, NULL);
int op = luaL_checkoption(L, 2, "all", catnames);
lua_pushstring(L, setlocale(cat[op], l));
return 1;
}
static int os_exit (lua_State *L) {
int status;
if (lua_isboolean(L, 1))
status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
else
status = luaL_optint(L, 1, EXIT_SUCCESS);
if (lua_toboolean(L, 2))
lua_close(L);
if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */
return 0;
}
static const luaL_Reg syslib[] = {
{"clock", os_clock},
{"date", os_date},
{"difftime", os_difftime},
{"execute", os_execute},
{"exit", os_exit},
{"getenv", os_getenv},
{"remove", os_remove},
{"rename", os_rename},
{"setlocale", os_setlocale},
{"time", os_time},
{"tmpname", os_tmpname},
{NULL, NULL}
};
/* }====================================================== */
LUAMOD_API int luaopen_os (lua_State *L) {
luaL_newlib(L, syslib);
return 1;
}

Some files were not shown because too many files have changed in this diff Show more