mirror of
https://github.com/g012/l65.git
synced 2024-12-28 10:30:18 +00:00
Added CMake builder.
This commit is contained in:
parent
e808ee4e43
commit
55381d271b
109
CMakeLists.txt
Normal file
109
CMakeLists.txt
Normal file
@ -0,0 +1,109 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
project(l65)
|
||||
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||
|
||||
set(L65_SOURCE_DIR ${PROJECT_SOURCE_DIR})
|
||||
set(L65_BINARY_DIR ${PROJECT_BINARY_DIR})
|
||||
|
||||
set(L65_VERSION_MAJOR "1")
|
||||
set(L65_VERSION_MINOR "0")
|
||||
set(L65_VERSION_REVISION "0")
|
||||
set(L65_VERSION "${L65_VERSION_MAJOR}.${L65_VERSION_MINOR}.${L65_VERSION_REVISION}")
|
||||
configure_file("${L65_SOURCE_DIR}/l65cfg.lua.in" "${L65_BINARY_DIR}/l65cfg.lua")
|
||||
|
||||
set(LINKLIBS)
|
||||
|
||||
if (MSVC)
|
||||
|
||||
set(USE_MSVC_RUNTIME_LIBRARY_DLL OFF CACHE BOOL "" FORCE)
|
||||
|
||||
add_definitions(-D_HAS_EXCEPTIONS=0 -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE)
|
||||
add_definitions(-DNOMINMAX -D_USE_MATH_DEFINES)
|
||||
add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
|
||||
foreach (flag CMAKE_C_FLAGS
|
||||
CMAKE_C_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_CXX_FLAGS
|
||||
CMAKE_CXX_FLAGS_DEBUG
|
||||
CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
if (${flag} MATCHES "/MD")
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
|
||||
endif()
|
||||
if (${flag} MATCHES "/MDd")
|
||||
string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}")
|
||||
endif()
|
||||
if(${flag} MATCHES "/EHsc")
|
||||
string(REGEX REPLACE "/EHsc" "/EHs-c-" ${flag} "${${flag}}")
|
||||
endif()
|
||||
if(${flag} MATCHES "/GR")
|
||||
string(REGEX REPLACE "/GR" "/GR-" ${flag} "${${flag}}")
|
||||
endif()
|
||||
if(${flag} MATCHES "/Gm")
|
||||
string(REGEX REPLACE "/Gm" "/Gm-" ${flag} "${${flag}}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
add_compile_options(/WX /MP /fp:fast /volatile:iso)
|
||||
add_compile_options(/wd4103 /wd4244 /wd4456 /wd4554 /wd4557 /wd4702 /wd6255 /wd6262 /wd28278)
|
||||
|
||||
else ()
|
||||
|
||||
if (APPLE)
|
||||
add_definitions(-DLUA_USE_MACOSX)
|
||||
else ()
|
||||
add_definitions(-DLUA_USE_LINUX)
|
||||
endif ()
|
||||
|
||||
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||
|
||||
add_compile_options(-fno-strict-aliasing -fomit-frame-pointer -ffast-math -fvisibility=hidden -fno-threadsafe-statics -fvisibility-inlines-hidden)
|
||||
add_compile_options(-fno-rtti -fno-exceptions)
|
||||
add_compile_options(-Werror -Wsign-compare -Wno-dangling-else -Wno-missing-braces -Wno-unused-function -Wno-shift-op-parentheses -Wno-unused-variable -Wno-switch -Wno-parentheses)
|
||||
|
||||
endif()
|
||||
|
||||
set(L65_SOURCES
|
||||
${L65_SOURCE_DIR}/lfs.c
|
||||
${L65_SOURCE_DIR}/lpeg.c
|
||||
${L65_SOURCE_DIR}/main.c
|
||||
)
|
||||
set(L65_HEADERS
|
||||
${L65_SOURCE_DIR}/lua.h
|
||||
${L65_BINARY_DIR}/scripts.h
|
||||
)
|
||||
set(L65_RESOURCES
|
||||
${L65_SOURCE_DIR}/6502.lua
|
||||
${L65_SOURCE_DIR}/l65.lua
|
||||
${L65_BINARY_DIR}/l65cfg.lua
|
||||
${L65_SOURCE_DIR}/vcs.l65
|
||||
)
|
||||
|
||||
add_executable(embed ${L65_SOURCE_DIR}/embed.c)
|
||||
file(GLOB L65_FILES ${L65_SOURCE_DIR}/*.l65)
|
||||
add_custom_command(
|
||||
OUTPUT ${L65_BINARY_DIR}/scripts.h
|
||||
COMMAND embed -o ${L65_BINARY_DIR}/scripts.h ${L65_SOURCE_DIR}/6502.lua ${L65_SOURCE_DIR}/l65.lua ${L65_BINARY_DIR}/l65cfg.lua ${L65_FILES}
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${L65_SOURCES} ${L65_HEADERS} ${L65_RESOURCES})
|
||||
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 99)
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE "${L65_SOURCE_DIR}" "${L65_BINARY_DIR}")
|
||||
|
||||
if (MSVC)
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/INCREMENTAL:NO /MANIFEST:NO /SUBSYSTEM:CONSOLE /ENTRY:mainCRTStartup")
|
||||
|
||||
elseif (UNIX)
|
||||
|
||||
list(APPEND LINKLIBS m dl)
|
||||
|
||||
endif()
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} ${LINKLIBS})
|
152
embed.c
Normal file
152
embed.c
Normal file
@ -0,0 +1,152 @@
|
||||
#define LUA_IMPLEMENTATION
|
||||
#include "lua.h"
|
||||
|
||||
#define PROGNAME "embed" /* default program name */
|
||||
#define OUTPUT "scripts.h" /* default output file */
|
||||
|
||||
static int dumping = 1; /* dump bytecodes? */
|
||||
static int stripping = 0; /* strip debug information? */
|
||||
static char Output[] = { OUTPUT }; /* default output file name */
|
||||
static const char* output = Output; /* actual output file name */
|
||||
static const char* progname = PROGNAME; /* actual program name */
|
||||
|
||||
static void fatal(const char* message)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", progname, message);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void cannot(const char* what)
|
||||
{
|
||||
fprintf(stderr, "%s: cannot %s %s: %s\n", progname, what, output, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void usage(const char* message)
|
||||
{
|
||||
if (*message == '-')
|
||||
fprintf(stderr, "%s: unrecognized option '%s'\n", progname, message);
|
||||
else
|
||||
fprintf(stderr, "%s: %s\n", progname, message);
|
||||
fprintf(stderr,
|
||||
"usage: %s [options] [filenames]\n"
|
||||
"Available options are:\n"
|
||||
" -o name output to file 'name' (default is \"%s\")\n"
|
||||
, progname, Output);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#define IS(s) (strcmp(argv[i],s)==0)
|
||||
|
||||
static int doargs(int argc, char* argv[])
|
||||
{
|
||||
int i;
|
||||
if (argv[0] != NULL && *argv[0] != 0) progname = argv[0];
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (*argv[i] != '-') /* end of options; keep it */
|
||||
break;
|
||||
else if (IS("--")) /* end of options; skip it */
|
||||
{
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
else if (IS("-")) /* end of options; use stdin */
|
||||
break;
|
||||
else if (IS("-o")) /* output file */
|
||||
{
|
||||
output = argv[++i];
|
||||
if (output == NULL || *output == 0 || (*output == '-' && output[1] != 0))
|
||||
usage("'-o' needs argument");
|
||||
if (IS("-")) output = NULL;
|
||||
}
|
||||
else /* unknown option */
|
||||
usage(argv[i]);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
#define FUNCTION "(function()end)();"
|
||||
|
||||
static int w_o;
|
||||
static int writer(lua_State* L, const void* p, size_t size, void* f)
|
||||
{
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
if ((i+w_o) % 32 == 0) fprintf(f, "\n");
|
||||
fprintf(f, "0x%02X, ", (int)(((unsigned char*)p)[i]));
|
||||
}
|
||||
w_o += size;
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
static int pmain(lua_State* L)
|
||||
{
|
||||
int argc = (int)lua_tointeger(L, 1);
|
||||
char** argv = (char**)lua_touserdata(L, 2);
|
||||
int i;
|
||||
if (!lua_checkstack(L, argc)) fatal("too many input files");
|
||||
FILE* f = (output == NULL) ? stdout : fopen(output, "wb");
|
||||
if (f == NULL) cannot("open");
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
int compile = 0;
|
||||
const char* filename = IS("-") ? NULL : argv[i];
|
||||
if (!filename) fatal("invalid input file");
|
||||
char *ufname = strdup(filename);
|
||||
int fnix = 0; for (int i = 0; ufname[i]; ++i) { if (ufname[i] == '/' || ufname[i] == '\\') fnix = i + 1; if (ufname[i] == '.') ufname[i] = '_'; }
|
||||
char *name = malloc(1024);
|
||||
sprintf(name, "script_%s", ufname + fnix);
|
||||
free(ufname);
|
||||
int fnl = strlen(filename);
|
||||
compile = fnl > 4 && !strcmp(".lua", filename + fnl - 4);
|
||||
if (compile)
|
||||
{
|
||||
if (luaL_loadfile(L, filename) != LUA_OK) fatal(lua_tostring(L, -1));
|
||||
fprintf(f, "static const unsigned char %s[] = {", name);
|
||||
w_o = 0;
|
||||
lua_dump(L, writer, f, 0);
|
||||
lua_pop(L, 1);
|
||||
fprintf(f, "\n};\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE* l = fopen(filename, "rb"); if (!l) cannot("open");
|
||||
fseek(l, 0, SEEK_END);
|
||||
int size = (int)ftell(l);
|
||||
rewind(l);
|
||||
unsigned char *buffer = malloc(size);
|
||||
if (size != fread(buffer, 1, size, l)) fatal("failed reading input file");
|
||||
fclose(l);
|
||||
fprintf(f, "static const char %s[] = {", name);
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
if (i % 32 == 0) fprintf(f, "\n");
|
||||
fprintf(f, "0x%02X, ", (int)buffer[i]);
|
||||
}
|
||||
fprintf(f, "\n};\n");
|
||||
free(buffer);
|
||||
}
|
||||
free(name);
|
||||
}
|
||||
if (ferror(f)) cannot("write");
|
||||
if (fclose(f)) cannot("close");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
lua_State* L;
|
||||
int i = doargs(argc, argv);
|
||||
argc -= i; argv += i;
|
||||
if (argc <= 0) usage("no input files given");
|
||||
L = luaL_newstate();
|
||||
if (L == NULL) fatal("cannot create state: not enough memory");
|
||||
lua_pushcfunction(L, &pmain);
|
||||
lua_pushinteger(L, argc);
|
||||
lua_pushlightuserdata(L, argv);
|
||||
if (lua_pcall(L, 2, 0, 0) != LUA_OK) fatal(lua_tostring(L, -1));
|
||||
lua_close(L);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
28
l65.lua
28
l65.lua
@ -2478,15 +2478,31 @@ l65 = {
|
||||
loadfile_org = loadfile,
|
||||
dofile_org = dofile,
|
||||
}
|
||||
do
|
||||
local getembedded = type(arg[-1]) == 'function' and arg[-1]
|
||||
l65.load_embedded = function(name)
|
||||
if not getembedded then return end
|
||||
local src,isl65 = getembedded(name)
|
||||
if not src then return end
|
||||
if isl65 then
|
||||
local filename = name .. '.l65'
|
||||
local st, ast = assert(l65.parse(src))
|
||||
local bc = assert(l65.load_org(l65.format(ast), filename))
|
||||
return bc, filename
|
||||
else
|
||||
local filename = name .. '.lua'
|
||||
local bc = assert(l65.load_org(src, filename))
|
||||
return bc, filename
|
||||
end
|
||||
end
|
||||
end
|
||||
l65.searcher = function(name)
|
||||
local filename,err = package.searchpath(name, l65.search_path, '.', '.')
|
||||
if not filename then return err end
|
||||
local file = io.open(filename, 'rb')
|
||||
if not file then return "failed to open " .. filename .. " for reading" end
|
||||
local file = assert(io.open(filename, 'rb'))
|
||||
local src = file:read('*a')
|
||||
file:close()
|
||||
local st, ast = l65.parse(src)
|
||||
if not st then print(ast) return end
|
||||
local st, ast = assert(l65.parse(src))
|
||||
local bc = assert(l65.load_org(l65.format(ast), filename))
|
||||
return bc, filename
|
||||
end
|
||||
@ -2543,6 +2559,7 @@ l65.uninstallhooks = function()
|
||||
dofile = l65.dofile_org
|
||||
end
|
||||
end
|
||||
table.insert(package.searchers, l65.searcher_index, l65.load_embedded)
|
||||
l65.installhooks()
|
||||
|
||||
function getopt(optstring, ...)
|
||||
@ -2578,8 +2595,9 @@ function getopt(optstring, ...)
|
||||
end)
|
||||
end
|
||||
|
||||
local cfg=require"l65cfg" l65.cfg=cfg
|
||||
local version = function()
|
||||
print("1.0.0")
|
||||
print(string.format("l65 %s", cfg.version))
|
||||
end
|
||||
local usage = function()
|
||||
print(string.format([[
|
||||
|
8
l65cfg.lua
Normal file
8
l65cfg.lua
Normal file
@ -0,0 +1,8 @@
|
||||
local M = {}
|
||||
|
||||
M.major = 1
|
||||
M.minor = 0
|
||||
M.revision = 0
|
||||
M.version = "1.0.0"
|
||||
|
||||
return M
|
8
l65cfg.lua.in
Normal file
8
l65cfg.lua.in
Normal file
@ -0,0 +1,8 @@
|
||||
local M = {}
|
||||
|
||||
M.major = ${L65_VERSION_MAJOR}
|
||||
M.minor = ${L65_VERSION_MINOR}
|
||||
M.revision = ${L65_VERSION_REVISION}
|
||||
M.version = "${L65_VERSION}"
|
||||
|
||||
return M
|
16
lfs.c
16
lfs.c
@ -2,6 +2,8 @@
|
||||
* lfs.c and lfs.h mixed together
|
||||
*/
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
/*
|
||||
** LuaFileSystem
|
||||
** Copyright Kepler Project 2003 - 2016 (http://keplerproject.github.io/luafilesystem)
|
||||
@ -16,9 +18,9 @@
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define chdir(p) (_chdir(p))
|
||||
#define getcwd(d, s) (_getcwd(d, s))
|
||||
#define rmdir(p) (_rmdir(p))
|
||||
//#define chdir(p) (_chdir(p))
|
||||
//#define getcwd(d, s) (_getcwd(d, s))
|
||||
//#define rmdir(p) (_rmdir(p))
|
||||
#define LFS_EXPORT __declspec (dllexport)
|
||||
#ifndef fileno
|
||||
#define fileno(f) (_fileno(f))
|
||||
@ -102,12 +104,6 @@ LFS_EXPORT int luaopen_lfs (lua_State *L);
|
||||
#define LFS_MAXPATHLEN MAXPATHLEN
|
||||
#endif
|
||||
|
||||
//#include <lua.h>
|
||||
//#include <lauxlib.h>
|
||||
//#include <lualib.h>
|
||||
|
||||
//#include "lfs.h"
|
||||
|
||||
#define LFS_VERSION "1.6.3"
|
||||
#define LFS_LIBNAME "lfs"
|
||||
|
||||
@ -325,7 +321,7 @@ static int lfs_lock_dir(lua_State *L) {
|
||||
lua_pushnil(L); lua_pushstring(L, strerror(errno)); return 2;
|
||||
}
|
||||
strcpy(ln, path); strcat(ln, lockfile);
|
||||
if((fd = CreateFile(ln, GENERIC_WRITE, 0, NULL, CREATE_NEW,
|
||||
if((fd = CreateFileA(ln, GENERIC_WRITE, 0, NULL, CREATE_NEW,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE) {
|
||||
int en = GetLastError();
|
||||
free(ln); lua_pushnil(L);
|
||||
|
3
lpeg.c
3
lpeg.c
@ -7,6 +7,7 @@
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "lua.h"
|
||||
|
||||
// only exported function
|
||||
int luaopen_lpeg (lua_State *L);
|
||||
@ -25,8 +26,10 @@ int luaopen_lpeg (lua_State *L);
|
||||
|
||||
|
||||
#if !defined(LPEG_DEBUG)
|
||||
#ifndef NDEBUG
|
||||
#define NDEBUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#define VERSION "1.0.1"
|
||||
|
2
lua.h
2
lua.h
@ -13930,7 +13930,7 @@ static int luai_searcherpreload (lua_State *L) {
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
|
||||
if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */
|
||||
lua_pushfstring(L, "\n\tno luai_field package.preload['%s']", name);
|
||||
lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
70
main.c
70
main.c
@ -1,15 +1,79 @@
|
||||
#define LUA_IMPLEMENTATION
|
||||
#include "lua.h"
|
||||
#include "scripts.h"
|
||||
|
||||
extern int luaopen_lpeg(lua_State *L);
|
||||
extern int luaopen_lfs(lua_State *L);
|
||||
|
||||
static struct script { const char *name; int t; const char *data; size_t sz; } embedded[] = {
|
||||
{ "l65cfg", 0, script_l65cfg_lua, sizeof(script_l65cfg_lua) },
|
||||
{ "vcs", 1, script_vcs_l65, sizeof(script_vcs_l65) },
|
||||
};
|
||||
|
||||
static int getembedded(lua_State *L)
|
||||
{
|
||||
const char *name = lua_tostring(L, 1);
|
||||
for (struct script *s = embedded, *e = s + sizeof(embedded) / sizeof(embedded[0]); s != e; ++s)
|
||||
{
|
||||
if (!strcmp(s->name, name))
|
||||
{
|
||||
lua_pushlstring(L, s->data, s->sz);
|
||||
lua_pushboolean(L, s->t);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msghandler(lua_State *L)
|
||||
{
|
||||
const char *msg = lua_tostring(L, 1);
|
||||
if (msg == NULL)
|
||||
{
|
||||
if (luaL_callmeta(L, 1, "__tostring") && lua_type(L, -1) == LUA_TSTRING)
|
||||
return 1;
|
||||
msg = lua_pushfstring(L, "(error object is a %s value)", luaL_typename(L, 1));
|
||||
}
|
||||
luaL_traceback(L, L, msg, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
lua_State *L = luaL_newstate();
|
||||
luaL_openlibs(L);
|
||||
luaL_require(L, "lpeg", luaopen_lpeg, 1); lua_pop(L, 1);
|
||||
luaL_require(L, "lfs", luaopen_lfs, 1); lua_pop(L, 1);
|
||||
return 0;
|
||||
luaL_requiref(L, "lpeg", luaopen_lpeg, 1); lua_pop(L, 1);
|
||||
luaL_requiref(L, "lfs", luaopen_lfs, 1); lua_pop(L, 1);
|
||||
|
||||
// preload embedded lua scripts
|
||||
luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE);
|
||||
luaL_loadbufferx(L, script_6502_lua, sizeof(script_6502_lua), "6502.lua", "b");
|
||||
lua_setfield(L, -2, "6502");
|
||||
lua_pop(L, 1);
|
||||
|
||||
// error handler
|
||||
lua_pushcfunction(L, msghandler);
|
||||
// l65.lua script
|
||||
luaL_loadbufferx(L, script_l65_lua, sizeof(script_l65_lua), "l65.lua", "b");
|
||||
// arg[] table
|
||||
lua_createtable(L, argc-1, 2);
|
||||
lua_pushcfunction(L, getembedded); // pass embedded script lookup function as arg[-1]
|
||||
lua_rawseti(L, -2, -1);
|
||||
for (int i = 0; i < argc; i++) lua_pushstring(L, argv[i]), lua_rawseti(L, -2, i);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setglobal(L, "arg");
|
||||
// ... arguments
|
||||
{ int i; for (i = 1; i < argc; ++i) lua_rawgeti(L, -i, i); lua_remove(L, -i); }
|
||||
// call l65
|
||||
int status = lua_pcall(L, argc-1, 0, -argc-1);
|
||||
if (status != LUA_OK)
|
||||
{
|
||||
const char *msg = lua_tostring(L, -1);
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
lua_pop(L, 1); // remove msghandler
|
||||
lua_close(L);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user