@@ -0,0 +1,126 @@


function juno.onLoad(dt)
G.field = juno.Buffer.fromBlank(G.width, G.height)
G.field:drawBox(0, 0, G.width, G.height)
G.tickTimer = 0
-- Initialise player
G.player = {
x = 20,
y = G.height / 2,
direction = "down",
color = { 1, 1, 1 },
}
-- Initialise AIs
G.ai = {}
for i = 1, 3 do
table.insert(G.ai, {
x = ((G.width - 40) / 3) * i + 20,
y = G.height / 2,
dead = false,
direction = "down",
turnTimer = 0,
turnRate = 10 + math.random(20),
color = ({ { 1, 0, 0 }, { 0, 1, 1 }, { 1, 1, 0 } })[i],
})
end
end


function juno.onKeyDown(k)
-- Handle player movement keys
if k == "left" or k == "up" or k == "down" or k == "right" then
G.player.direction = k
end
-- Handle game restart key
if k == "r" then
juno.onLoad()
end
end


local function isPixelBlack(x, y)
local r, g, b = G.field:getPixel(x, y)
return r == 0 and g == 0 and b == 0
end


local function nextPosition(bike, steps)
steps = steps or 1
return ({
left = function() return bike.x - steps, bike.y end,
right = function() return bike.x + steps, bike.y end,
up = function() return bike.x, bike.y - steps end,
down = function() return bike.x, bike.y + steps end,
})[bike.direction]()
end


local function randomDirection()
return ({ "left", "right", "up", "down" })[math.random(4)]
end


local function updateAi(ai, dt)
-- Do random turn timer and random turn
ai.turnTimer = ai.turnTimer - 1
if ai.turnTimer <= 0 then
ai.turnTimer = math.random(ai.turnRate)
ai.direction = randomDirection()
end
-- Do obstacle avoidance
for lookahead = 4, 1, -1 do
for i = 1, 8 do
if not isPixelBlack(nextPosition(ai, lookahead)) then
ai.direction = randomDirection()
end
end
end
end


local function updateBike(bike)
-- Don't update the bike if its dead
if bike.dead then
return
end
-- Move bike
bike.x, bike.y = nextPosition(bike)
-- Kill the bike if it collided with something
if not isPixelBlack(bike.x, bike.y) then
bike.dead = true
return
end
-- Draw bike
G.field:setPixel(bike.x, bike.y, unpack(bike.color))
end


local function onTick()
-- Update AIs
for i, ai in ipairs(G.ai) do
updateAi(ai)
updateBike(ai)
end
-- Update player
updateBike(G.player)
end


function juno.onUpdate(dt)
-- Update tick timer
G.tickTimer = G.tickTimer - dt
while G.tickTimer <= 0 do
onTick()
G.tickTimer = G.tickTimer + .03
end
-- Player is dead? Restart the game
if G.player.dead then
juno.onLoad()
end
end


function juno.onDraw()
juno.graphics.copyPixels(G.field, 0, 0, nil, G.scale)
end
@@ -0,0 +1,71 @@
--
-- Copyright (c) 2015 rxi
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the MIT license. See LICENSE for details.
--


local function checkArg(idx, cond, msg)
if not cond then
error("bad argument #" .. idx .. ", " .. msg, 3)
end
end


function juno.Buffer:getSize()
return self:getWidth(), self:getHeight()
end


local defaultFont = juno.Font.fromEmbedded()

local fontTexCache = {}
setmetatable(fontTexCache, {
__index = function(t, k)
fontTexCache[k] = {}
return fontTexCache[k]
end,
__mode = "v",
})

function juno.Buffer:drawText(font, text, x, y, width)
if type(font) ~= "userdata" then
return self:drawText(defaultFont, font, text, x, y, width)
end
checkArg(3, x == nil or type(x) == "number", "expected number")
checkArg(4, y == nil or type(y) == "number", "expected number")
checkArg(5, width == nil or type(width) == "number", "expected number")
text = tostring(text)
if width then
-- Word wrapped multi line
local height = font:getHeight()
local line
for word in text:gmatch("%S+") do
local tmp = (line and (line .. " ") or "") .. word
if font:getWidth(tmp) > width then
juno.graphics.drawText(font, line, x, y)
y = y + height
line = word
else
line = tmp
end
end
self:drawText(font, line, x, y)
elseif text:find("\n") then
-- Multi line
local height = font:getHeight()
for line in (text.."\n"):gmatch("(.-)\n") do
self:drawText(font, line, x, y)
y = y + height
end
else
-- Single line
local tex = fontTexCache[font][text]
if not tex then
tex = font:render(text)
fontTexCache[font][text] = tex
end
self:drawBuffer(tex, x, y)
end
end
@@ -0,0 +1,246 @@
--
-- Copyright (c) 2015 rxi
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the MIT license. See LICENSE for details.
--


juno.debug = juno.debug or {}

local font
local inited = false
local enabled = false
local focused = false
local indicators = {}
local lines = {}
local inputbuf = ""

-- Override print
local _print = print
print = function(...)
_print(...)
-- Convert all arguments to string and store in table
local t = {}
for i = 1, select("#", ...) do
t[#t + 1] = tostring(select(i, ...))
end
local str = table.concat(t, " ")
-- Multiple lines? Split and insert, else just insert the string
if str:match("\n") then
for line in (str .. "\n"):gmatch("(.-)\n") do
table.insert(lines, line)
end
else
table.insert(lines, str)
end
while #lines > 6 do
table.remove(lines, 1)
end
end


local indicatorIdx
local textRegionWidth = 20

local function newIndicator(fn, min, max)
min = min or 0
max = max or 0
local trueMin, trueMax = min, max
-- Get idx
indicatorIdx = indicatorIdx and (indicatorIdx + 1) or 0
-- Init
local pad = 8
local height = 26
local maxBars = 16
local barUpdatePeriod = 1
local yoffset = pad + height * indicatorIdx
local lastUpdate = juno.time.getNow()
local bars = {}
local lastMin = min
local lastMax = max
-- Fill bars with zeros
for i = 1, maxBars do
bars[i] = 0
end
-- Return draw function
return function()
local txt, val = fn()
-- Resize text region?
textRegionWidth = math.max(font:getWidth(txt) + 8, textRegionWidth)
-- Update bars?
if juno.time.getNow() > lastUpdate + barUpdatePeriod then
table.remove(bars)
table.insert(bars, 1, val)
min = math.min(trueMin, unpack(bars))
max = math.max(trueMax, unpack(bars))
lastUpdate = juno.time.getNow()
end
-- Draw text
local w = textRegionWidth
juno.graphics.drawRect(pad / 2, yoffset - (pad / 2),
w, height - 1, 0, 0, 0, .8)
juno.graphics.drawText(font, txt, pad, yoffset)
-- Draw bars
juno.graphics.drawRect(pad / 2 + w + 1, yoffset - (pad / 2),
73, height - 1, 0, 0, 0, .8)
for i, v in ipairs(bars) do
local x = math.floor((bars[i] - min) / (max - min) * 16)
juno.graphics.drawRect(pad / 2 + w + 1 + (i - 1) * 4 + 5,
yoffset + 16 - x, 3, x,
nil, nil, nil, (i == 1) and 1 or .4)
end
end
end


local function draw()
-- Not enabled? Don't draw
if not enabled then
return
end
-- Draw
juno.graphics.reset()
-- Draw indicators
for i, v in ipairs(indicators) do
v()
end
-- Draw console input text
local w = 300
if focused then
local h = font:getHeight()
local y = juno.graphics.getHeight() - 8 - h
local caret = (juno.time.getTime() % .6 < .3) and "_" or ""
w = math.max(w, font:getWidth(inputbuf .. "_"))
juno.graphics.drawRect(4, juno.graphics.getHeight() - h - 12,
w + 8, h + 8,
0, 0, 0, .8)
juno.graphics.drawText(font, inputbuf .. caret, 8, y)
end
-- Draw console output text
if #lines > 0 then
local h = font:getHeight()
local rh = #lines * h + 8
local oy = focused and (h + 9) or 0
for i, v in ipairs(lines) do
w = math.max(w, font:getWidth(v))
end
juno.graphics.drawRect(4, juno.graphics.getHeight() - 4 - rh - oy,
w + 8, rh,
0, 0, 0, .8)
for i, v in ipairs(lines) do
local y = juno.graphics.getHeight() - 8 - (#lines - i + 1) * h
juno.graphics.drawText(font, v, 8, y - oy)
end
end
end


local function init()
-- Init font
font = juno.Font.fromEmbedded(12)
-- Init indicators
juno.debug.addIndicator(function()
local r = juno.time.getFps()
return r .. "fps", r
end)
juno.debug.addIndicator(function()
local r = collectgarbage("count")
return string.format("%.2fmb", r / 1024), r
end)
-- Override present function to draw the debug information before calling the
-- proper present function
local present = juno.graphics.present
juno.graphics.present = function(...)
draw()
present(...)
end
-- Set init flag
inited = true
end


local onError = function(msg)
print("error: " .. msg:match("[^\n]+"))
end

function juno.debug._onEvent(e)
-- Handle console's keyboard input
if e.type == "keydown" and enabled and focused then
if e.key == "backspace" then
inputbuf = inputbuf:sub(1, #inputbuf - 1)
elseif e.key == "return" then
local fn, err = loadstring(inputbuf, "=input")
if fn then
xpcall(fn, onError)
else
onError(err)
end
inputbuf = ""
elseif e.char then
inputbuf = inputbuf .. e.char
end
end
end


function juno.debug._draw()
draw()
end


function juno.debug.setVisible(x)
enabled = x and true or false
if enabled and not inited then
init()
end
end

function juno.debug.getVisible(x)
return enabled
end


function juno.debug.setFocused(x)
focused = x and true or false
end

function juno.debug.getFocused(x)
return focused
end


function juno.debug.clear()
while #lines > 0 do
table.remove(lines)
end
end


function juno.debug.addIndicator(fn, min, max)
-- Error check
local str, num = fn()
if type(str) ~= "string" or type(num) ~= "number" then
error("expected indicator function to return string and number", 2)
end
if min and type(min) ~= "number" then
error("expected `min` to be a number", 2)
end
if max and type(max) ~= "number" then
error("expected `max` to be a number", 2)
end
-- Create, add and return
local indicator = newIndicator(fn, min, max)
table.insert(indicators, indicator)
return indicator
end


function juno.debug.removeIndicator(indicator)
for i, v in ipairs(indicators) do
if v == indicator then
table.remove(indicators, i)
return
end
end
end
BIN +212 KB src/embed/font.ttf
Binary file not shown.
@@ -0,0 +1,46 @@
--
-- Copyright (c) 2015 rxi
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the MIT license. See LICENSE for details.
--


-- Override juno.graphics.init function
local init = juno.graphics.init

juno.graphics.init = function(...)
-- Do init
local screen = init(...)
juno.graphics.screen = screen
-- Bind the screen buffer's methods to the graphics module
for k, v in pairs(juno.Buffer) do
if not juno.graphics[k] then
juno.graphics[k] = function(...)
return v(screen, ...)
end
end
end
-- Unbind Buffer constructors (which make no sense bound)
juno.graphics.fromBlank = nil
juno.graphics.fromFile = nil
juno.graphics.fromString = nil
-- Override juno.graphics.clear() to use _clearColor if available
local clear = juno.graphics.clear
function juno.graphics.clear(r, g, b, a)
local c = juno.graphics._clearColor
r = r or (c and c[1])
g = g or (c and c[2])
b = b or (c and c[3])
clear(r, g, b, 1)
end
-- Return main screen buffer
return screen
end


function juno.graphics.setClearColor(...)
juno.graphics._clearColor = { ... }
end


@@ -0,0 +1,341 @@
--
-- Copyright (c) 2015 rxi
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the MIT license. See LICENSE for details.
--


local function call(fn, ...)
if fn then return fn(...) end
end

local function merge(...)
local res = {}
for i = 1, select("#", ...) do
local t = select(i, ...)
if t then
for k, v in pairs(t) do
res[k] = v
end
end
end
return res
end

local function push(arr, ...)
for i = 1, select("#", ...) do
table.insert(arr, (select(i, ...)))
end
end


local doneOnError = false
local exit = os.exit
local traceback = debug.traceback

local function onError(msg)
if not doneOnError then
doneOnError = true
juno.onError(msg, traceback())
else
print("\n" .. msg .. "\n" .. traceback())
exit(1)
end
end

-------------------------------------------------------------------------------
-- Init callbacks
-------------------------------------------------------------------------------

local eventHandlers = {
keydown = function(e)
call(juno.keyboard._onEvent, e)
call(juno.debug._onEvent, e)
call(juno.onKeyDown, e.key, e.char)
end,
keyup = function(e)
call(juno.keyboard._onEvent, e)
call(juno.onKeyUp, e.key)
end,
mousemove = function(e)
call(juno.mouse._onEvent, e)
call(juno.onMouseMove, e.x, e.y)
end,
mousebuttondown = function(e)
call(juno.mouse._onEvent, e)
call(juno.onMouseDown, e.x, e.y, e.button)
end,
mousebuttonup = function(e)
call(juno.mouse._onEvent, e)
call(juno.onMouseUp, e.x, e.y, e.button)
end,
quit = function(e)
call(juno.onQuit)
os.exit()
end,
}

local function onStepMain()
for i, e in ipairs(juno.system.poll()) do
call(eventHandlers[e.type], e)
end
call(juno.time.step)
call(juno.onUpdate, call(juno.time.getDelta))
call(juno.graphics.clear)
call(juno.onDraw)
call(juno.debug._draw)
call(juno.keyboard.reset)
call(juno.mouse.reset)
end

function juno._onStep()
xpcall(onStepMain, onError)
end

function juno._onAudio(...)
local res
local args = { ... }
xpcall(function()
res = call(juno.onAudio, unpack(args))
end, onError)
return res
end

local pcallFunc
local pcallArgs = {}
local pcallWrap = function()
return pcallFunc(unpack(pcallArgs))
end

function juno._pcall(fn, ...)
pcallFunc = fn
-- Fill argument table with new arguments, discard old args
local n = select("#", ...)
for i = 1, n do
pcallArgs[i] = select(i, ...)
end
if #pcallArgs > n then
for i = n + 1, #pcallArgs do
pcallArgs[i] = nil
end
end
-- Do call
return xpcall(pcallWrap, onError)
end

function juno.onError(msg, stacktrace)
-- Create and print error string
local tab = " "
local str =
msg:gsub("\t", tab):gsub("\n+$", "") .. "\n\n" ..
stacktrace:gsub("\t", tab)
print("Error:\n" .. str)
-- Override event handlers
eventHandlers = {
quit = function() os.exit() end,
keydown = function(e) if e.key == "escape" then os.exit() end end,
}
-- Disable debug
call(juno.debug.setVisible, false)
call(juno.mouse.setVisible, true)

-- Init error state
local font, bigfont
local done = false
local alpha = 0

function juno.onUpdate()
-- The initialisation of the error state's graphics is defered to the
-- first onUpdate() call in case the error occurs in the audio thread in
-- which case it won't be able to change the openGL state
juno.graphics.reset()
juno.graphics.setClearColor(.15, .16, .2)
font = juno.Font.fromEmbedded(14)
bigfont = juno.Font.fromEmbedded(40)
-- Init update function
function juno.onUpdate(dt)
if alpha == 1 then
done = true
else
alpha = math.min(alpha + dt / .5, 1)
end
end
end

function juno.onAudio() end

function juno.onDraw()
juno.graphics.setAlpha(alpha)
juno.graphics.drawText(bigfont, "Error", 40, 40)
juno.graphics.drawText(font, str, 40, 120)
-- As this screen won't change after its faded in we can sleep here to
-- avoid having to redraw too often -- this will reduce CPU usage
if done then
juno.time.sleep(.1)
end
end
end


-------------------------------------------------------------------------------
-- Init filesystem
-------------------------------------------------------------------------------

-- Mount project paths
if juno._argv[2] then
-- Try to mount all arguments as package
for i = 2, #juno._argv do
juno.fs.mount(juno._argv[i])
end
else
-- Try to mount default packages (pak0, pak1, etc.)
local dirs = { juno.system.info("exedir") }
if juno.system.info("os") == "osx" then
table.insert(dirs, juno.system.info("exedir") .. "/../Resources")
end
for _, dir in ipairs(dirs) do
local idx = 0
while juno.fs.mount(dir .. "/pak" .. idx) do
idx = idx + 1
end
if idx ~= 0 then break end
end
end

-- Add filesystem-compatible package loader
table.insert(package.loaders, 1, function(modname)
modname = modname:gsub("%.", "/")
for x in package.path:gmatch("[^;]+") do
local filename = x:gsub("?", modname)
if juno.fs.exists(filename) then
return assert(loadstring(juno.fs.read(filename), "=" .. filename))
end
end
end)

-- Add extra package paths
package.path = package.path .. ";?/init.lua"



-------------------------------------------------------------------------------
-- Init config
-------------------------------------------------------------------------------

local c = {}
if juno.fs.exists("config.lua") then
c = call(require, "config")
end

local config = merge({
title = "Juno " .. juno.getVersion(),
width = 500,
height = 500,
maxfps = 60,
samplerate = 44100,
buffersize = 2048,
fullscreen = false,
resizable = false,
}, c)

if not config.identity then
config.identity = config.title:gsub("[^%w]", ""):lower()
end


-------------------------------------------------------------------------------
-- Init filesystem write path
-------------------------------------------------------------------------------

local appdata = juno.system.info("appdata")
local path = appdata .. "/juno/" .. config.identity

juno.fs.setWritePath(path)
juno.fs.mount(path)


-------------------------------------------------------------------------------
-- Init modules
-------------------------------------------------------------------------------

juno.graphics.init(config.width, config.height, config.title,
config.fullscreen, config.resizable)
juno.graphics.setMaxFps(config.maxfps)
juno.graphics.setClearColor(0, 0, 0)
juno.audio.init(config.samplerate, config.buffersize)


-------------------------------------------------------------------------------
-- Init project
-------------------------------------------------------------------------------

if juno.fs.exists("main.lua") then
-- Load project file
xpcall(function() require "main" end, onError)
else
-- No project file -- init "no project loaded" screen
local w, h = juno.graphics.getSize()
local txt = juno.Font.fromEmbedded(14):render("No project loaded")
local txtPost = txt:clone()
local txtMask = txt:clone()
local particles = {}

function juno.onLoad()
juno.graphics.setClearColor(0.15, 0.15, 0.15)
for i = 1, 30 do
local p = {
x = 0,
y = (i / 30) * 100,
z = 0,
r = (i / 30) * 2,
}
table.insert(particles, p)
end
end

function juno.onUpdate(dt)
local n = juno.time.getTime()
for _, p in ipairs(particles) do
p.x = math.cos(n * p.r) * 100
p.z = math.sin(n * p.r)
end
end

function juno.onKeyDown(k)
if k == "escape" then
os.exit()
end
end

function juno.onDraw()
-- Draw particles
juno.graphics.setBlend("add")
local lastx, lasty
for _, p in ipairs(particles) do
local x, y = (p.x * p.z) + w / 2, (p.y * p.z) + w / 2
juno.graphics.setAlpha(p.a)
juno.graphics.drawPixel(x, y)
if lastx then
juno.graphics.setAlpha(.3)
juno.graphics.drawLine(x, y, lastx, lasty)
end
lastx, lasty = x, y
end
-- Draw text
local n = juno.time.getTime() * 2
local x = (1 + math.sin(n)) * txtMask:getWidth() / 2
txtPost:copyPixels(txt)
txtMask:clear(1, 1, 1, .5)
txtMask:drawRect(x - 10, 0, 20, 100, 1, 1, 1, .6)
txtMask:drawRect(x - 5, 0, 10, 100, 1, 1, 1, 1)
juno.bufferfx.mask(txtPost, txtMask)
local tx, ty = (h - txt:getWidth()) / 2, (h - txt:getHeight()) / 2
juno.graphics.reset()
juno.graphics.draw(txtPost, tx, ty + 130)
end

end

xpcall(function() call(juno.onLoad) end, onError)

@@ -0,0 +1,55 @@
--
-- Copyright (c) 2015 rxi
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the MIT license. See LICENSE for details.
--


-- The table is checked and created here if it does not exist, at the time of
-- writing this the juno.keyboard does not have a C module, and so the table
-- won't exist yet.
juno.keyboard = juno.keyboard or {}

local keysDown = {}
local keysPressed = {}


function juno.keyboard._onEvent(e)
if e.type == "keydown" then
keysDown[e.key] = true
keysPressed[e.key] = true
elseif e.type == "keyup" then
keysDown[e.key] = nil
end
end


function juno.keyboard.reset()
for k in pairs(keysPressed) do
keysPressed[k] = nil
end
end


function juno.keyboard.isDown(...)
for i = 1, select("#", ...) do
local k = select(i, ...)
if keysDown[k] then
return true
end
end
return false
end


function juno.keyboard.wasPressed(...)
for i = 1, select("#", ...) do
local k = select(i, ...)
if keysPressed[k] then
return true
end
end
return false
end

@@ -0,0 +1,67 @@
--
-- Copyright (c) 2015 rxi
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the MIT license. See LICENSE for details.
--


local position = { x = 0, y = 0 }
local buttonsDown = {}
local buttonsPressed = {}


function juno.mouse._onEvent(e)
if e.type == "mousemove" then
position.x, position.y = e.x, e.y
elseif e.type == "mousebuttondown" then
buttonsDown[e.button] = true
buttonsPressed[e.button] = true
elseif e.type == "mousebuttonup" then
buttonsDown[e.button] = nil
end
end


function juno.mouse.reset()
for k in pairs(buttonsPressed) do
buttonsPressed[k] = nil
end
end


function juno.mouse.isDown(...)
for i = 1, select("#", ...) do
local b = select(i, ...)
if buttonsDown[b] then
return true
end
end
return false
end


function juno.mouse.wasPressed(...)
for i = 1, select("#", ...) do
local b = select(i, ...)
if buttonsPressed[b] then
return true
end
end
return false
end


function juno.mouse.getPosition()
return position.x, position.y
end


function juno.mouse.getX()
return position.x
end


function juno.mouse.getY()
return position.y
end
@@ -0,0 +1,47 @@
--
-- Copyright (c) 2015 rxi
--
-- This library is free software; you can redistribute it and/or modify it
-- under the terms of the MIT license. See LICENSE for details.
--


local last = 0
local delta = 0
local average = 0
local avgTimer = 0
local avgAcc = 1
local avgCount = 1


function juno.time.step()
local now = juno.time.getTime()
if last == 0 then last = now end
delta = now - last
last = now
avgTimer = avgTimer - delta
avgAcc = avgAcc + delta
avgCount = avgCount + 1
if avgTimer <= 0 then
average = avgAcc / avgCount
avgTimer = avgTimer + 1
avgCount = 0
avgAcc = 0
end
end


function juno.time.getDelta()
return delta
end


function juno.time.getAverage()
return average
end


function juno.time.getFps()
return math.floor(1 / average + .5)
end

507 src/fs.c

Large diffs are not rendered by default.

@@ -0,0 +1,49 @@
/**
* Copyright (c) 2015 rxi
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MIT license. See LICENSE for details.
*/


#ifndef FS_H
#define FS_H

typedef struct fs_FileListNode {
char *name;
struct fs_FileListNode *next;
} fs_FileListNode;

enum {
FS_ESUCCESS = 0,
FS_EFAILURE = -1,
FS_EOUTOFMEM = -2,
FS_EBADPATH = -3,
FS_EBADFILENAME = -4,
FS_ENOWRITEPATH = -5,
FS_ECANTOPEN = -6,
FS_ECANTREAD = -7,
FS_ECANTWRITE = -8,
FS_ECANTDELETE = -9,
FS_ECANTMKDIR = -10,
FS_ENOTEXIST = -11,
};

const char *fs_errorStr(int err);
void fs_deinit(void);
int fs_mount(const char *path);
int fs_unmount(const char *path);
int fs_setWritePath(const char *path);
int fs_exists(const char *filename);
int fs_modified(const char *filename, unsigned *mtime);
int fs_size(const char *filename, size_t *size);
void *fs_read(const char *filename, size_t *size);
int fs_isDir(const char *filename);
fs_FileListNode *fs_listDir(const char *path);
void fs_freeFileList(fs_FileListNode *list);
int fs_write(const char *filename, const void *data, int size);
int fs_append(const char *filename, const void *data, int size);
int fs_delete(const char *filename);
int fs_makeDirs(const char *path);

#endif
@@ -0,0 +1,147 @@
#ifndef LEXTLIB_LUA52_H
#define LEXTLIB_LUA52_H

/**
* The original version of this file is located at
* https://github.com/devurandom/lextlib/blob/master/lextlib_lua52.h
*
* Its license is as follows:
*
* Copyright (c) 2012 Dennis Schridde
*
* 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.
*/


#include <assert.h>

//#include <lua.h>
//#include <lauxlib.h>


#if LUA_VERSION_NUM < 502
/* Error codes for lua_load: */
# define LUA_OK 0
/* WARNING: This error does not exist in Lua 5.1 */
# define LUA_ERRGCMM (-1)

/* Comparison types for lua_compare: */
# define LUA_OPEQ 0
# define LUA_OPLT 1
# define LUA_OPLE 2

/* WARNING: Not entirely correct, but should work anyway */
# define lua_rawlen lua_objlen

# define lua_absindex(L, i) (((i) > 0 || (i) < LUA_REGISTRYINDEX) ? (i) : lua_gettop(L)+(i)+1)

/* WARNING: Something very different, but it might get your job done */
# define lua_getuservalue lua_getfenv
# define lua_setuservalue lua_setfenv

/* WARNING: Probably slower than Lua 5.2's implementation */
# define lua_compare luaX52_lua_compare

# define lua_tonumberx(L,i,b) (lua_isnumber(L,(i)) ? (*(b)=1, lua_tonumber(L,(i))) : (*(b)=0, 0))
# define lua_tointegerx(L,i,b) (lua_isnumber(L,(i)) ? (*(b)=1, lua_tointeger(L,(i))) : (*(b)=0, 0))

# define luaL_getsubtable luaX52_luaL_getsubtable

# define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))

# define luaL_newlibtable(L,l) (lua_createtable(L,0,sizeof(l)))

# define luaL_requiref(L,l,f,g) luaX52_luaL_requiref(L,(l),(f),(g))

# define luaL_setfuncs luaX52_luaL_setfuncs

# define luaL_setmetatable(L,t) (luaL_getmetatable(L,t), lua_setmetatable(L,-2))

# define luaL_testudata(L,i,t) luaX52_luaL_testudata(L,(i),(t))

static inline void luaX52_luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) {
luaL_checkstack(L, nup, "too many upvalues");
for (; l->name != NULL; l++) { /* fill the table with given functions */
for (int 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 */
}

static inline int luaX52_lua_compare(lua_State *L, int index1, int index2, int op) {
assert(op == LUA_OPEQ || op == LUA_OPLT || op == LUA_OPLE);
switch (op) {
case LUA_OPEQ:
return lua_equal(L, index1, index2);
case LUA_OPLT:
return lua_lessthan(L, index1, index2);
case LUA_OPLE:
return lua_lessthan(L, index1, index2) || lua_equal(L, index1, index2);
default:
return luaL_error(L, "Call to lua_compare with unsupported operator %d", op);
}
}

static inline int luaX52_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 */
}
}

static inline void luaX52_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 */
}
}

static inline void *luaX52_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 */
}

#endif


#endif

Large diffs are not rendered by default.

@@ -0,0 +1,16 @@
/*
** $Id: lapi.h,v 2.2.1.1 2007/12/27 13:02:25 roberto Exp $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/

#ifndef lapi_h
#define lapi_h


#include "lobject.h"


LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);

#endif

Large diffs are not rendered by default.

@@ -0,0 +1,174 @@
/*
** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 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"


#if defined(LUA_COMPAT_GETN)
LUALIB_API int (luaL_getn) (lua_State *L, int t);
LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
#else
#define luaL_getn(L,i) ((int)lua_objlen(L, i))
#define luaL_setn(L,i,j) ((void)0) /* no op! */
#endif

#if defined(LUA_COMPAT_OPENLIB)
#define luaI_openlib luaL_openlib
#endif


/* 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 (luaI_openlib) (lua_State *L, const char *libname,
const luaL_Reg *l, int nup);
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l);
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 int (luaL_typerror) (lua_State *L, int narg, const char *tname);
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 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_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_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);

LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
const char *name);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);

LUALIB_API lua_State *(luaL_newstate) (void);


LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
const char *r);

LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
const char *fname, int szhint);




/*
** ===============================================================
** some useful macros
** ===============================================================
*/

#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)))

/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/



typedef struct luaL_Buffer {
char *p; /* current position in buffer */
int lvl; /* number of strings in the stack (level) */
lua_State *L;
char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer;

#define luaL_addchar(B,c) \
((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
(*(B)->p++ = (char)(c)))

/* compatibility only */
#define luaL_putchar(B,c) luaL_addchar(B,c)

#define luaL_addsize(B,n) ((B)->p += (n))

LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
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);


/* }====================================================== */


/* compatibility with ref system */

/* pre-defined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)

#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
(lua_pushstring(L, "unlocked references are obsolete"), lua_error(L), 0))

#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))

#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))


#define luaL_reg luaL_Reg

#endif


Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,76 @@
/*
** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 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
*/
typedef enum BinOpr {
OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
OPR_CONCAT,
OPR_NE, OPR_EQ,
OPR_LT, OPR_LE, 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.s.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)

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 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_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_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_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);
LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);


#endif
@@ -0,0 +1,398 @@
/*
** $Id: ldblib.c,v 1.104.1.4 2009/08/04 18:50:18 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"



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_pushboolean(L, lua_setmetatable(L, 1));
return 1;
}


static int db_getfenv (lua_State *L) {
luaL_checkany(L, 1);
lua_getfenv(L, 1);
return 1;
}


static int db_setfenv (lua_State *L) {
luaL_checktype(L, 2, LUA_TTABLE);
lua_settop(L, 2);
if (lua_setfenv(L, 1) == 0)
luaL_error(L, LUA_QL("setfenv")
" cannot change environment of given object");
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 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, "flnSu");
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);
if (strchr(options, 'n')) {
settabss(L, "name", ar.name);
settabss(L, "namewhat", ar.namewhat);
}
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;
if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */
return luaL_argerror(L, arg+1, "level out of range");
name = lua_getlocal(L1, &ar, luaL_checkint(L, arg+2));
if (name) {
lua_xmove(L1, L, 1);
lua_pushstring(L, name);
lua_pushvalue(L, -2);
return 2;
}
else {
lua_pushnil(L);
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);
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);
if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
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 const char KEY_HOOK = 'h';


static void hookf (lua_State *L, lua_Debug *ar) {
static const char *const hooknames[] =
{"call", "return", "line", "count", "tail return"};
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushlightuserdata(L, 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 void gethooktable (lua_State *L) {
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
lua_rawget(L, LUA_REGISTRYINDEX);
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
lua_createtable(L, 0, 1);
lua_pushlightuserdata(L, (void *)&KEY_HOOK);
lua_pushvalue(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX);
}
}


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);
}
gethooktable(L);
lua_pushlightuserdata(L, L1);
lua_pushvalue(L, arg+1);
lua_rawset(L, -3); /* set new hook */
lua_pop(L, 1); /* remove hook table */
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);
lua_pushlightuserdata(L, L1);
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];
fputs("lua_debug> ", stderr);
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)) {
fputs(lua_tostring(L, -1), stderr);
fputs("\n", stderr);
}
lua_settop(L, 0); /* remove eventual returns */
}
}


#define LEVELS1 12 /* size of the first part of the stack */
#define LEVELS2 10 /* size of the second part of the stack */

static int db_errorfb (lua_State *L) {
int level;
int firstpart = 1; /* still before eventual `...' */
int arg;
lua_State *L1 = getthread(L, &arg);
lua_Debug ar;
if (lua_isnumber(L, arg+2)) {
level = (int)lua_tointeger(L, arg+2);
lua_pop(L, 1);
}
else
level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
if (lua_gettop(L) == arg)
lua_pushliteral(L, "");
else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
else lua_pushliteral(L, "\n");
lua_pushliteral(L, "stack traceback:");
while (lua_getstack(L1, level++, &ar)) {
if (level > LEVELS1 && firstpart) {
/* no more than `LEVELS2' more levels? */
if (!lua_getstack(L1, level+LEVELS2, &ar))
level--; /* keep going */
else {
lua_pushliteral(L, "\n\t..."); /* too many levels */
while (lua_getstack(L1, level+LEVELS2, &ar)) /* find last levels */
level++;
}
firstpart = 0;
continue;
}
lua_pushliteral(L, "\n\t");
lua_getinfo(L1, "Snl", &ar);
lua_pushfstring(L, "%s:", ar.short_src);
if (ar.currentline > 0)
lua_pushfstring(L, "%d:", ar.currentline);
if (*ar.namewhat != '\0') /* is there a name? */
lua_pushfstring(L, " in function " LUA_QS, ar.name);
else {
if (*ar.what == 'm') /* main? */
lua_pushfstring(L, " in main chunk");
else if (*ar.what == 'C' || *ar.what == 't')
lua_pushliteral(L, " ?"); /* C function or tail call */
else
lua_pushfstring(L, " in function <%s:%d>",
ar.short_src, ar.linedefined);
}
lua_concat(L, lua_gettop(L) - arg);
}
lua_concat(L, lua_gettop(L) - arg);
return 1;
}


static const luaL_Reg dblib[] = {
{"debug", db_debug},
{"getfenv", db_getfenv},
{"gethook", db_gethook},
{"getinfo", db_getinfo},
{"getlocal", db_getlocal},
{"getregistry", db_getregistry},
{"getmetatable", db_getmetatable},
{"getupvalue", db_getupvalue},
{"setfenv", db_setfenv},
{"sethook", db_sethook},
{"setlocal", db_setlocal},
{"setmetatable", db_setmetatable},
{"setupvalue", db_setupvalue},
{"traceback", db_errorfb},
{NULL, NULL}
};


LUALIB_API int luaopen_debug (lua_State *L) {
luaL_register(L, LUA_DBLIBNAME, dblib);
return 1;
}

Large diffs are not rendered by default.

@@ -0,0 +1,33 @@
/*
** $Id: ldebug.h,v 2.3.1.1 2007/12/27 13:02:25 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 getline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)

#define resethookcount(L) (L->hookcount = L->basehookcount)


LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
const char *opname);
LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
LUAI_FUNC void luaG_errormsg (lua_State *L);
LUAI_FUNC int luaG_checkcode (const Proto *pt);
LUAI_FUNC int luaG_checkopenop (Instruction i);

#endif

Large diffs are not rendered by default.

@@ -0,0 +1,57 @@
/*
** $Id: ldo.h,v 2.7.1.1 2007/12/27 13:02:25 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 ((char *)L->stack_last - (char *)L->top <= (n)*(int)sizeof(TValue)) \
luaD_growstack(L, n); \
else condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1));


#define incr_top(L) {luaD_checkstack(L,1); L->top++;}

#define savestack(L,p) ((char *)(p) - (char *)L->stack)
#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))

#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))


/* results from luaD_precall */
#define PCRLUA 0 /* initiated a call to a Lua function */
#define PCRC 1 /* did a call to a C function */
#define PCRYIELD 2 /* C funtion yielded */


/* 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);
LUAI_FUNC void luaD_callhook (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);
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_reallocCI (lua_State *L, int newsize);
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);

LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);

LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);

#endif

@@ -0,0 +1,164 @@
/*
** $Id: ldump.c,v 2.8.1.1 2007/12/27 13:02:25 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 || getstr(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,D);
}
}

#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)

static void DumpFunction(const Proto* f, const TString* p, 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(ttype(o),D);
switch (ttype(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); /* cannot happen */
break;
}
}
n=f->sizep;
DumpInt(n,D);
for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
}

static void DumpDebug(const Proto* f, DumpState* D)
{
int i,n;
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],D);
}

static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
{
DumpString((f->source==p || D->strip) ? NULL : f->source,D);
DumpInt(f->linedefined,D);
DumpInt(f->lastlinedefined,D);
DumpChar(f->nups,D);
DumpChar(f->numparams,D);
DumpChar(f->is_vararg,D);
DumpChar(f->maxstacksize,D);
DumpCode(f,D);
DumpConstants(f,D);
DumpDebug(f,D);
}

static void DumpHeader(DumpState* D)
{
char 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,NULL,&D);
return D.status;
}
@@ -0,0 +1,174 @@
/*
** $Id: lfunc.c,v 2.12.1.2 2007/12/28 14:58:43 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 nelems, Table *e) {
Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
luaC_link(L, obj2gco(c), LUA_TFUNCTION);
c->c.isC = 1;
c->c.env = e;
c->c.nupvalues = cast_byte(nelems);
return c;
}


Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
luaC_link(L, obj2gco(c), LUA_TFUNCTION);
c->l.isC = 0;
c->l.env = e;
c->l.nupvalues = cast_byte(nelems);
while (nelems--) c->l.upvals[nelems] = NULL;
return c;
}


UpVal *luaF_newupval (lua_State *L) {
UpVal *uv = luaM_new(L, UpVal);
luaC_link(L, obj2gco(uv), LUA_TUPVAL);
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 = ngcotouv(*pp))->v >= level) {
lua_assert(p->v != &p->u.value);
if (p->v == level) { /* found a corresponding upvalue? */
if (isdead(g, obj2gco(p))) /* is it dead? */
changewhite(obj2gco(p)); /* ressurect it */
return p;
}
pp = &p->next;
}
uv = luaM_new(L, UpVal); /* not found: create a new one */
uv->tt = LUA_TUPVAL;
uv->marked = luaC_white(g);
uv->v = level; /* current value lives in the stack */
uv->next = *pp; /* chain it in the proper position */
*pp = obj2gco(uv);
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 = ngcotouv(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);
setobj(L, &uv->u.value, uv->v);
uv->v = &uv->u.value; /* now current value lives here */
luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
}
}
}


Proto *luaF_newproto (lua_State *L) {
Proto *f = luaM_new(L, Proto);
luaC_link(L, obj2gco(f), LUA_TPROTO);
f->k = NULL;
f->sizek = 0;
f->p = NULL;
f->sizep = 0;
f->code = NULL;
f->sizecode = 0;
f->sizelineinfo = 0;
f->sizeupvalues = 0;
f->nups = 0;
f->upvalues = NULL;
f->numparams = 0;
f->is_vararg = 0;
f->maxstacksize = 0;
f->lineinfo = NULL;
f->sizelocvars = 0;
f->locvars = NULL;
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, Instruction);
luaM_freearray(L, f->p, f->sizep, Proto *);
luaM_freearray(L, f->k, f->sizek, TValue);
luaM_freearray(L, f->lineinfo, f->sizelineinfo, int);
luaM_freearray(L, f->locvars, f->sizelocvars, struct LocVar);
luaM_freearray(L, f->upvalues, f->sizeupvalues, TString *);
luaM_free(L, f);
}


void luaF_freeclosure (lua_State *L, Closure *c) {
int size = (c->c.isC) ? sizeCclosure(c->c.nupvalues) :
sizeLclosure(c->l.nupvalues);
luaM_freemem(L, c, size);
}


/*
** 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 */
}

@@ -0,0 +1,34 @@
/*
** $Id: lfunc.h,v 2.4.1.1 2007/12/27 13:02:25 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, Table *e);
LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
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_freeclosure (lua_State *L, Closure *c);
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

Large diffs are not rendered by default.

@@ -0,0 +1,110 @@
/*
** $Id: lgc.h,v 2.15.1.1 2007/12/27 13:02:25 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/

#ifndef lgc_h
#define lgc_h


#include "lobject.h"


/*
** Possible states of the Garbage Collector
*/
#define GCSpause 0
#define GCSpropagate 1
#define GCSsweepstring 2
#define GCSsweep 3
#define GCSfinalize 4


/*
** some userful 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))
#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2)))



/*
** Layout for bit use in `marked' field:
** bit 0 - object is white (type 0)
** bit 1 - object is white (type 1)
** bit 2 - object is black
** bit 3 - for userdata: has been finalized
** bit 3 - for tables: has weak keys
** bit 4 - for tables: has weak values
** bit 5 - object is fixed (should not be collected)
** bit 6 - object is "super" fixed (only the main thread)
*/


#define WHITE0BIT 0
#define WHITE1BIT 1
#define BLACKBIT 2
#define FINALIZEDBIT 3
#define KEYWEAKBIT 3
#define VALUEWEAKBIT 4
#define FIXEDBIT 5
#define SFIXEDBIT 6
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)


#define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT)
#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
#define isgray(x) (!isblack(x) && !iswhite(x))

#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
#define isdead(g,v) ((v)->gch.marked & otherwhite(g) & WHITEBITS)

#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_checkGC(L) { \
condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \
if (G(L)->totalbytes >= G(L)->GCthreshold) \
luaC_step(L); }


#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \
luaC_barrierf(L,obj2gco(p),gcvalue(v)); }

#define luaC_barriert(L,t,v) { if (valiswhite(v) && isblack(obj2gco(t))) \
luaC_barrierback(L,t); }

#define luaC_objbarrier(L,p,o) \
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \
luaC_barrierf(L,obj2gco(p),obj2gco(o)); }

#define luaC_objbarriert(L,t,o) \
{ if (iswhite(obj2gco(o)) && isblack(obj2gco(t))) luaC_barrierback(L,t); }

LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all);
LUAI_FUNC void luaC_callGCTM (lua_State *L);
LUAI_FUNC void luaC_freeall (lua_State *L);
LUAI_FUNC void luaC_step (lua_State *L);
LUAI_FUNC void luaC_fullgc (lua_State *L);
LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);


#endif
@@ -0,0 +1,38 @@
/*
** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h
*/


#define linit_c
#define LUA_LIB

#include "lua.h"

#include "lualib.h"
#include "lauxlib.h"


static const luaL_Reg lualibs[] = {
{"", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
{NULL, NULL}
};


LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib = lualibs;
for (; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_pushstring(L, lib->name);
lua_call(L, 1, 0);
}
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,81 @@
/*
** $Id: llex.h,v 1.58.1.1 2007/12/27 13:02:25 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

/* maximum length of a reserved word */
#define TOKEN_LEN (sizeof("function")/sizeof(char))


/*
* 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_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_NUMBER,
TK_NAME, TK_STRING, TK_EOS
};

/* number of reserved words */
#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))


/* array with token `names' */
LUAI_DATA const char *const luaX_tokens [];


typedef union {
lua_Number r;
TString *ts;
} SemInfo; /* semantics information */


typedef struct Token {
int token;
SemInfo seminfo;
} Token;


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; /* `FuncState' is private to the parser */
struct lua_State *L;
ZIO *z; /* input stream */
Mbuffer *buff; /* buffer for tokens */
TString *source; /* current source 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);
LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
LUAI_FUNC void luaX_next (LexState *ls);
LUAI_FUNC void luaX_lookahead (LexState *ls);
LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token);
LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);


#endif
@@ -0,0 +1,128 @@
/*
** $Id: llimits.h,v 1.69.1.1 2007/12/27 13:02:25 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 LUAI_UINT32 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_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 */
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 */
#ifdef lua_assert

#define check_exp(c,e) (lua_assert(c), (e))
#define api_check(l,e) lua_assert(e)

#else

#define lua_assert(c) ((void)0)
#define check_exp(c,e) (e)
#define api_check luai_apicheck

#endif


#ifndef UNUSED
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
#endif


#ifndef cast
#define cast(t, exp) ((t)(exp))
#endif

#define cast_byte(i) cast(lu_byte, (i))
#define cast_num(i) cast(lua_Number, (i))
#define cast_int(i) cast(int, (i))



/*
** 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) */
#ifndef MINSTRTABSIZE
#define MINSTRTABSIZE 32
#endif


/* minimum size for string buffer */
#ifndef LUA_MINBUFFER
#define LUA_MINBUFFER 32
#endif


#ifndef lua_lock
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
#endif

#ifndef luai_threadyield
#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
#endif


/*
** macro to control inclusion of some hard tests on stack reallocation
*/
#ifndef HARDSTACKTESTS
#define condhardstacktests(x) ((void)0)
#else
#define condhardstacktests(x) x
#endif

#endif
@@ -0,0 +1,263 @@
/*
** $Id: lmathlib.c,v 1.67.1.1 2007/12/27 13:02:25 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 (3.14159265358979323846)
#define RADIANS_PER_DEGREE (PI/180.0)



static int math_abs (lua_State *L) {
lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
return 1;
}

static int math_sin (lua_State *L) {
lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
return 1;
}

static int math_sinh (lua_State *L) {
lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
return 1;
}

static int math_cos (lua_State *L) {
lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
return 1;
}

static int math_cosh (lua_State *L) {
lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
return 1;
}

static int math_tan (lua_State *L) {
lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
return 1;
}

static int math_tanh (lua_State *L) {
lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
return 1;
}

static int math_asin (lua_State *L) {
lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
return 1;
}

static int math_acos (lua_State *L) {
lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
return 1;
}

static int math_atan (lua_State *L) {
lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
return 1;
}

static int math_atan2 (lua_State *L) {
lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
return 1;
}

static int math_ceil (lua_State *L) {
lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
return 1;
}

static int math_floor (lua_State *L) {
lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
return 1;
}

static int math_fmod (lua_State *L) {
lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
return 1;
}

static int math_modf (lua_State *L) {
double ip;
double fp = 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, sqrt(luaL_checknumber(L, 1)));
return 1;
}

static int math_pow (lua_State *L) {
lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
return 1;
}

static int math_log (lua_State *L) {
lua_pushnumber(L, log(luaL_checknumber(L, 1)));
return 1;
}

static int math_log10 (lua_State *L) {
lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
return 1;
}

static int math_exp (lua_State *L) {
lua_pushnumber(L, 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, frexp(luaL_checknumber(L, 1), &e));
lua_pushinteger(L, e);
return 2;
}

static int math_ldexp (lua_State *L) {
lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
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 */
int u = luaL_checkint(L, 1);
luaL_argcheck(L, 1<=u, 1, "interval is empty");
lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
break;
}
case 2: { /* lower and upper limits */
int l = luaL_checkint(L, 1);
int u = luaL_checkint(L, 2);
luaL_argcheck(L, l<=u, 2, "interval is empty");
lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
break;
}
default: return luaL_error(L, "wrong number of arguments");
}
return 1;
}


static int math_randomseed (lua_State *L) {
srand(luaL_checkint(L, 1));
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},
{"log10", math_log10},
{"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
*/
LUALIB_API int luaopen_math (lua_State *L) {
luaL_register(L, LUA_MATHLIBNAME, mathlib);
lua_pushnumber(L, PI);
lua_setfield(L, -2, "pi");
lua_pushnumber(L, HUGE_VAL);
lua_setfield(L, -2, "huge");
#if defined(LUA_COMPAT_MOD)
lua_getfield(L, -1, "fmod");
lua_setfield(L, -2, "mod");
#endif
return 1;
}