Data update
This commit is contained in:
parent
4d5544505c
commit
4924dd0264
3073 changed files with 55820 additions and 4408 deletions
|
|
@ -0,0 +1,21 @@
|
|||
// Save this section as main.c
|
||||
#include <stdio.h>
|
||||
|
||||
extern int Query (char * Data, size_t * Length);
|
||||
|
||||
int main (int argc, char * argv [])
|
||||
{
|
||||
char Buffer [1024];
|
||||
size_t Size = sizeof (Buffer);
|
||||
|
||||
if (0 == Query (Buffer, &Size))
|
||||
{
|
||||
printf ("failed to call Query\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
char * Ptr = Buffer;
|
||||
while (Size-- > 0) putchar (*Ptr++);
|
||||
putchar ('\n');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# Save this section as a file called query.jl
|
||||
|
||||
function Query(buffer::Ptr{UInt8}, length::Ptr{Csize_t})::Cint
|
||||
""" Define the Query function to be called from C """
|
||||
|
||||
max_size = unsafe_load(length)
|
||||
data = "Hello from Julia!"
|
||||
bytes = codeunits(data)
|
||||
max_size < length(bytes) && return 0 # Failure: buffer too small
|
||||
for i in 1:length(bytes)
|
||||
unsafe_store!(buffer, bytes[i], i)
|
||||
end
|
||||
unsafe_store!(length, length(bytes))
|
||||
return 1
|
||||
end
|
||||
|
||||
Base.@export Query
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// save this section as query_wrapper.c
|
||||
|
||||
#include <julia.h>
|
||||
|
||||
JULIA_DEFINE_FAST_TLS()
|
||||
|
||||
int Query(char *Data, size_t *Length) {
|
||||
jl_init();
|
||||
|
||||
jl_eval_string("include(\"query.jl\")"); // Include the Julia file containing Query function
|
||||
|
||||
jl_function_t *func = jl_get_function(jl_main_module, "Query");
|
||||
if (!func) {
|
||||
jl_atexit_hook(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
jl_value_t *buffer = jl_ptr_to_array_1d(jl_uint8_type, Data, *Length, 0);
|
||||
jl_value_t *length = jl_box_uint64((uint64_t)Length);
|
||||
|
||||
// Call the query function within Julia
|
||||
jl_value_t *result = jl_call2(func, buffer, length);
|
||||
if (jl_exception_occurred()) {
|
||||
jl_atexit_hook(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get return value
|
||||
int ret = jl_unbox_int32(result);
|
||||
|
||||
jl_atexit_hook(0);
|
||||
return ret; // Return the result of the Query function from the C shared library
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# Save this section as compile.sh and run it in a terminal with all files in same directory
|
||||
gcc -shared -fPIC -o libquery.so query_wrapper.c -I$JULIA_DIR/include/julia -L$JULIA_DIR/lib -ljulia -Wl,-rpath,$JULIA_DIR/lib
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Compilation of libquery.so failed."
|
||||
exit 1
|
||||
fi
|
||||
echo "libquery.so compiled successfully."
|
||||
|
||||
gcc -o main main.c -L. -lquery
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error: Compilation of main failed."
|
||||
exit 1
|
||||
fi
|
||||
echo "main compiled successfully."
|
||||
|
||||
export LD_LIBRARY_PATH=.:$JULIA_DIR/lib:$LD_LIBRARY_PATH
|
||||
./main
|
||||
|
||||
echo "Script finished."
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
-- Query.lua
|
||||
|
||||
-- basic kv dbase
|
||||
function qdb_init ()
|
||||
qdb = {} -- global in lua
|
||||
qdb["who are you?"] = "I am Lua"
|
||||
qdb["what are you?"] = "I am a Lua virtual machine"
|
||||
qdb["when are you?"] = "I am live"
|
||||
qdb["where are you?"] = "Here I am"
|
||||
qdb["how are you?"] = "I am a fine"
|
||||
qdb["default"] = "unknown query"
|
||||
|
||||
end
|
||||
|
||||
-- call from C with key => Data
|
||||
function Query(k)
|
||||
|
||||
local key = string.lower(k)
|
||||
|
||||
if (qdb[key] == nil) then key = "default" end
|
||||
|
||||
lua_response = qdb[key]
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
/* Query_lua.c */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
|
||||
// tell lua how many args for a function
|
||||
typedef enum { NOARG, ONEARG, TWOARGS, THREEARGS } argcount;
|
||||
// 0 1 2 3
|
||||
|
||||
// diagnostics when things go wrong
|
||||
typedef enum { C_OK, C_FAILURE, LUA_FAILURE} exitcode;
|
||||
// 0 1 2
|
||||
|
||||
/* lua vars we will create or use */
|
||||
const char* lua_Query = "Query";
|
||||
const char* lua_Data = "Data";
|
||||
const char* lua_qdb_init = "qdb_init";
|
||||
const char* lua_qdb = "qdb";
|
||||
const char* lua_response = "lua_response";
|
||||
|
||||
|
||||
int LTop; // global C index to top of lua stack
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
int Query(char* Data, size_t * Length);
|
||||
|
||||
void fail(const char* fmsg, const char* errstr, exitcode ret);
|
||||
|
||||
lua_State* C_lua_init(const char* luafile);
|
||||
|
||||
bool C_push_string(lua_State* L, const char* name,
|
||||
const char* str, const size_t n);
|
||||
|
||||
bool C_get_string( lua_State * L, const char* src,
|
||||
char* dest, size_t max);
|
||||
|
||||
|
||||
// exit program with diagnostice and exitcode
|
||||
void fail(const char* fmsg, const char* errstr, exitcode ret) {
|
||||
|
||||
fprintf(stderr, "%s ", fmsg);
|
||||
|
||||
if (errstr != NULL){ fprintf(stderr, "%s ", errstr); }
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
|
||||
// push C string to lua
|
||||
bool C_push_string(lua_State* L, const char* name,
|
||||
const char* str, const size_t n){
|
||||
(void) n;
|
||||
lua_pushstring(L, str);
|
||||
lua_setglobal(L, name);
|
||||
return true;
|
||||
}
|
||||
|
||||
// get C string from lua string by variable var
|
||||
bool C_get_string( lua_State * L, const char* luavar,
|
||||
char* dest, size_t max){
|
||||
|
||||
const char* lstring = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
lua_getglobal(L, luavar);
|
||||
|
||||
if(!lua_isstring(L, -1)) {
|
||||
fail("expected a string", lua_tostring(L, -1), LUA_FAILURE);
|
||||
}
|
||||
|
||||
LTop = lua_gettop(L);
|
||||
|
||||
lstring = lua_tolstring(L, LTop, &max );
|
||||
len = strlen(lstring);
|
||||
|
||||
if (len > 0) {
|
||||
strncpy(dest, lstring, len);
|
||||
dest[len+1] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
initialize the lua vm
|
||||
load up the lua file
|
||||
any commands in the global area will run
|
||||
*/
|
||||
|
||||
lua_State* C_lua_init(const char* luafile) {
|
||||
|
||||
exitcode status = C_OK;
|
||||
|
||||
/// creates Lua machine & env
|
||||
lua_State* L = luaL_newstate();
|
||||
if (L == NULL) {
|
||||
fail("could not create lua state", "lua internal failure", LUA_FAILURE);
|
||||
}
|
||||
|
||||
// imports basic libs like string, io, os, table, utf-8, math
|
||||
luaL_openlibs(L);
|
||||
|
||||
// lua file to load
|
||||
status = luaL_loadfile(L, luafile);
|
||||
|
||||
if (status != LUA_OK){
|
||||
fail("loadfile failed", lua_tostring(L, -1), LUA_FAILURE);
|
||||
}
|
||||
|
||||
/* "priming run"
|
||||
SEE http://www.troubleshooters.com/codecorn/lua/lua_c_calls_lua.htm
|
||||
*/
|
||||
if (lua_pcall(L, 0, 0, 0) != LUA_OK) {
|
||||
fail("priming run failed",lua_tostring(L, -1), LUA_FAILURE);
|
||||
}
|
||||
|
||||
return L;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------
|
||||
function called by main in Query.c
|
||||
*/
|
||||
|
||||
int Query(char* Data, size_t * Length) {
|
||||
|
||||
/* ======= SETUP LUA ====== */
|
||||
// create Lua vm with file
|
||||
lua_State* L = C_lua_init("Query.lua");
|
||||
|
||||
// call db init
|
||||
lua_getglobal(L, lua_qdb_init);
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION); // optionally check lua type
|
||||
|
||||
int result = lua_pcall(L, NOARG, 0, 0); // execute lua func
|
||||
if (result != LUA_OK) {
|
||||
fail("failed to run qdb_init function", lua_tostring(L, -1), LUA_FAILURE);
|
||||
}
|
||||
|
||||
/* ======= RUN LUA CODE ========= */
|
||||
|
||||
// put Data into Lua env as a string
|
||||
C_push_string(L, lua_Data, Data, *Length-1);
|
||||
|
||||
/* set function to call and 1 arg(s) */
|
||||
lua_getglobal(L, lua_Query); // function
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
|
||||
lua_getglobal(L, lua_Data); // arg
|
||||
luaL_checktype(L, -1, LUA_TSTRING);
|
||||
|
||||
// call lua function with 1 arg*
|
||||
result = lua_pcall(L, ONEARG, LUA_MULTRET, 0);
|
||||
if (result != LUA_OK) {
|
||||
fail("failed to run Query function", lua_tostring(L, -1), LUA_FAILURE);
|
||||
}
|
||||
|
||||
// lua_response should have our answer
|
||||
char* response = calloc(*Length, sizeof(char));
|
||||
if (response == NULL) {
|
||||
fail("calloc failed allocation", NULL, C_FAILURE);
|
||||
}
|
||||
|
||||
// created within lua
|
||||
C_get_string(L, lua_response, response, *Length);
|
||||
|
||||
|
||||
/* ======== CLEANUP LUA ====== */
|
||||
|
||||
// clean up lua vars and close vm
|
||||
// (assign var = nil)
|
||||
lua_pushnil(L); lua_setglobal(L, lua_response);
|
||||
lua_pushnil(L); lua_setglobal(L, lua_Data);
|
||||
lua_pushnil(L); lua_setglobal(L, lua_Query);
|
||||
lua_pushnil(L); lua_setglobal(L, lua_qdb);
|
||||
lua_close(L); // lua is done
|
||||
|
||||
|
||||
/* ======= REPORT ====== */
|
||||
|
||||
size_t rlen = strlen(response);
|
||||
|
||||
if (rlen > 0) {
|
||||
strncpy(Data, response, *Length-1);
|
||||
Data[rlen] = '\0';
|
||||
free(response); // because dynamically allocated
|
||||
} else {
|
||||
fail("lua", "no response", LUA_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// end
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
gcc -std=c2x -Wall -Wextra \
|
||||
-I/usr/include/lua5.3 -o query \
|
||||
Query.c Query_lua.c \
|
||||
-L/usr/lib/x84_64-linux-gnu/ -l lua5.3
|
||||
Loading…
Add table
Add a link
Reference in a new issue