diff --git a/scripts/generate_header.sh b/scripts/generate_header.sh index afabad93..e250085d 100755 --- a/scripts/generate_header.sh +++ b/scripts/generate_header.sh @@ -23,16 +23,19 @@ discard_preprocessors() { # sed regex for extracting data from function signature # if this isn't regex, idk what is # LUA_API (return type as \2) (function name as \3) (args as \4) -sym_regex='^LUA\(LIB\)\?_API\s\+\([^(]\+\)\s*(\([^)]\+\))\s\+(\([^)]\+\))' +sym_regex='^LUA\(LIB\)\?_API\s\+\([^(]\+\)\s*(\([^)]\+\))\s\+(\([^)]\+\));' # get funcptr declarations ptrize() { - grep '^LUA' | sed -e "s/$sym_regex/static \2(*\3) (\4)/" + grep '^LUA' | sed -e "s/$sym_regex/static \2(*\3) (\4);/" +} + +import_sym() { + grep '^LUA' | sed -e "s/$sym_regex/\tIMPORT_SYMBOL(\3, \2, \4);/" } export_sym() { - # don't even bother reading this again - grep '^LUA' | sed -e "s/$sym_regex/\tIMPORT_SYMBOL(\3, \2, \4)/" + grep '^LUA' | sed -e "s/$sym_regex/\t\tEXPORT_SYMBOL(\3),/" } decl() { @@ -47,48 +50,134 @@ decl() { grep '^#' <<< "$header" } +decl_import() { + uncomment $1 | onelineize | import_sym +} + decl_export() { uncomment $1 | onelineize | export_sym } -LUA_PATH="$1" -cat << EOF -/** -The lite_xl plugin API is quite simple. Any shared library can be a plugin file, so long -as it has an entrypoint that looks like the following, where xxxxx is the plugin name: -#include "lite_xl_plugin_api.h" -int lua_open_lite_xl_xxxxx(lua_State* L, void* XL) { - lite_xl_plugin_init(XL); - ... - return 1; +generate_header() { + local LUA_PATH="$1" + echo "#ifndef LITE_XL_PLUGIN_API" + echo "#define LITE_XL_PLUGIN_API" + echo "/**" + echo "The lite_xl plugin API is quite simple. Any shared library can be a plugin file, so long" + echo "as it has an entrypoint that looks like the following, where xxxxx is the plugin name:" + echo '#include "lite_xl_plugin_api.h"' + echo "int lua_open_lite_xl_xxxxx(lua_State* L, void* XL) {" + echo " lite_xl_plugin_init(XL);" + echo " ..." + echo " return 1;" + echo "}" + echo "In linux, to compile this file, you'd do: 'gcc -o xxxxx.so -shared xxxxx.c'. Simple!" + echo "Due to the way the API is structured, you *should not* link or include lua libraries." + echo "This file was automatically generated by the below code. DO NOT MODIFY DIRECTLY." + echo + echo + cat "$0" + echo "**/" + echo "#include " + + decl "$LUA_PATH/lua.h" + decl "$LUA_PATH/lauxlib.h" + + echo "#define IMPORT_SYMBOL(name, ret, ...) name = (ret (*) (__VA_ARGS__)) symbol(#name)" + echo "static void lite_xl_plugin_init(void *XL) {" + echo -e "\tvoid* (*symbol)(const char *) = (void* (*) (const char *)) XL;" + + decl_import "$LUA_PATH/lua.h" + decl_import "$LUA_PATH/lauxlib.h" + + echo "}" + echo "#endif" } -In linux, to compile this file, you'd do: 'gcc -o xxxxx.so -shared xxxxx.c'. Simple! -Due to the way the API is structured, you *should not* link or include lua libraries. -This file was automatically generated by the below code. Do NOT MODIFY DIRECTLY. +generate_api_require() { + local LUA_PATH="$1" + echo "#ifndef API_REQUIRE_H" + echo "#define API_REQUIRE_H" + echo "/**" + echo "This file contains the function api_require that" + echo "returns a function pointer with it's corresponding name." + echo + echo "This file is automatically generated. DO NOT MODIFY." + echo "*/" + echo "#include " + echo "#include " + echo '#include "lua.h"' + echo '#include "lauxlib.h"' + echo + echo "typedef struct fnptr_s {" + echo -e "\tconst char* name;" + echo -e "\tvoid *addr;" + echo "} fnptr_t;" + echo + echo "#define EXPORT_SYMBOL(SYM) { #SYM, (void*)(SYM) }" + echo "static void *api_require(const char *symbol) {" + echo -e "\tstatic fnptr_t nodes[] = {" -EOF + decl_export "$LUA_PATH/lua.h" + decl_export "$LUA_PATH/lauxlib.h" -cat "$0" + echo -e "\t};" + echo -e "\tfor (int i = 0; i < sizeof(nodes) / sizeof(fnptr_t); i++)" + echo -e "\t\tif (strcmp(nodes[i].name, symbol) == 0)" + echo -e "\t\t\treturn nodes[i].addr;" + echo -e "\treturn NULL;" + echo "}" + echo "#endif" +} -cat << EOF -**/ +show_help() { + echo -e "Usage: $0 prefix" + echo + echo -e "Available options:" + echo + echo -e "-a\t--api-header\tGenerate lite_xl_plugin_api.h" + echo -e "-b\t--api-require\tGenerate api_require.h" + echo -e "-p\t--prefix\tSet prefix (where to find lua.h and lauxlib.h)" +} +main() { + local header=0 + local require=0 + local prefix="" -#ifndef LITE_XL_PLUGIN_API -#define LITE_XL_PLUGIN_API -EOF + for i in "$@"; do + case $i in + -h|--help) + show_help + exit 0 + ;; + -a|--api-header) + header=1 + shift + ;; + -b|--api-require) + require=1 + shift + ;; + -p|--prefix) + prefix="$2" + shift + shift + ;; + *) + ;; + esac + done -decl "$LUA_PATH/lua.h" -decl "$LUA_PATH/lauxlib.h" + if [[ "$header" -eq 1 ]]; then + generate_header "$prefix" + elif [[ "$require" -eq 1 ]]; then + generate_api_require "$prefix" + else + show_help + exit 1 + fi +} -echo "#define IMPORT_SYMBOL(name, ret, ...) name = (ret (*) (__VA_ARGS__)) symbol(#name)" -echo "static void lite_xl_plugin_init(void *XL) {" -echo -e "\tvoid* (*symbol)(const char *) = (void* (*) (const char *)) XL;" - -decl_export "$LUA_PATH/lua.h" -decl_export "$LUA_PATH/lauxlib.h" - -echo "}" -echo "#endif" +main "$@"