### Build and Link Lua Library Source: https://context7.com/citizenfx/lua/llms.txt Instructions for building the Lua static library (liblua.a) or object files, and examples of how to link against the library or object files in a C project using gcc. ```makefile # Build just the library make a # Build just the object files make o # Clean build artifacts make clean # The build produces: # - liblua.a: Static library containing core VM and standard libraries # - lua: Standalone interpreter executable ``` ```c # Link against liblua.a in your projects: gcc -o myapp myapp.c -L. -llua -lm -ldl -lreadline # Or use the object files directly: gcc -o myapp myapp.c lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o \ lfunc.o lgc.o llex.o lmem.o lobject.o lopcodes.o lparser.o lstate.o \ lstring.o ltable.o ltm.o lundump.o lvm.o lzio.o lauxlib.o lbaselib.o \ ldblib.o liolib.o lmathlib.o loslib.o ltablib.o lstrlib.o lutf8lib.o \ loadlib.o lcorolib.o linit.o -lm -ldl -lreadline ``` -------------------------------- ### Register C Functions for Lua Source: https://context7.com/citizenfx/lua/llms.txt Shows how to expose C functions to be called from Lua scripts. This involves defining C functions that adhere to the Lua C API and registering them using `lua_register`. The example includes functions for calculating factorials and splitting strings. ```c #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include #include // C function callable from Lua static int c_factorial(lua_State *L) { // Check argument and get value lua_Integer n = luaL_checkinteger(L, 1); // Validate input luaL_argcheck(L, n >= 0, 1, "must be non-negative"); // Calculate factorial lua_Integer result = 1; for (lua_Integer i = 2; i <= n; i++) { result *= i; } // Push result lua_pushinteger(L, result); return 1; // Number of return values } // C function with multiple return values static int c_split_name(lua_State *L) { const char *fullname = luaL_checkstring(L, 1); // Simple split on space const char *space = strchr(fullname, ' '); if (space) { lua_pushlstring(L, fullname, space - fullname); // First name lua_pushstring(L, space + 1); // Last name return 2; } else { lua_pushstring(L, fullname); lua_pushnil(L); return 2; } } int main(void) { lua_State *L = luaL_newstate(); if (L == NULL) return 1; luaL_openlibs(L); // Register C functions as global Lua functions lua_register(L, "factorial", c_factorial); lua_register(L, "split_name", c_split_name); // Test the registered functions const char *test = "print('5! =', factorial(5))\n" "local first, last = split_name('John Doe')\n" "print('First:', first, 'Last:', last)\n"; if (luaL_dostring(L, test) != LUA_OK) { fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); lua_close(L); return 1; } lua_close(L); return 0; } ``` -------------------------------- ### Lua Stack Manipulation Example (C) Source: https://context7.com/citizenfx/lua/llms.txt Illustrates how to interact with the Lua stack from C, including pushing various data types (nil, boolean, integer, number, string) and retrieving them. It also demonstrates checking the stack size, accessing elements by index, and removing elements using `lua_pop` and `lua_settop`. ```c #include "lua.h" #include "lauxlib.h" #include void demonstrate_stack(lua_State *L) { // Push various types onto the stack lua_pushnil(L); // index 1 lua_pushboolean(L, 1); // index 2 lua_pushinteger(L, 42); // index 3 lua_pushnumber(L, 3.14159); // index 4 lua_pushstring(L, "Hello, Lua!"); // index 5 // Get stack size int top = lua_gettop(L); printf("Stack size: %d\n", top); // Access values (1-indexed from bottom, negative from top) printf("Boolean at 2: %d\n", lua_toboolean(L, 2)); printf("Integer at 3: %lld\n", (long long)lua_tointeger(L, 3)); printf("Number at 4: %f\n", lua_tonumber(L, 4)); printf("String at 5: %s\n", lua_tostring(L, 5)); printf("String at -1: %s\n", lua_tostring(L, -1)); // Type checking if (lua_isstring(L, 5)) { printf("Index 5 is a string\n"); } // Remove elements lua_pop(L, 2); // Remove top 2 elements printf("Stack size after pop: %d\n", lua_gettop(L)); // Clear the stack lua_settop(L, 0); } ``` -------------------------------- ### Set and Get Global Variables in Lua from C Source: https://context7.com/citizenfx/lua/llms.txt This C function demonstrates how to set global variables (integer, string, boolean) in the Lua state and then execute Lua code that accesses and modifies these variables. It also shows how to retrieve a modified global variable back into C. Dependencies include the Lua C API headers. ```c #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include void globals_example(lua_State *L) { // Set global variables lua_pushinteger(L, 100); lua_setglobal(L, "score"); lua_pushstring(L, "Player One"); lua_setglobal(L, "player_name"); lua_pushboolean(L, 1); lua_setglobal(L, "game_active"); // Execute Lua code that uses these globals const char *code = "print('Player:', player_name)\n" "print('Score:', score)\n" "print('Active:', game_active)\n" "score = score + 50\n"; if (luaL_dostring(L, code) != LUA_OK) { fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); return; } // Read modified global back lua_getglobal(L, "score"); if (lua_isinteger(L, -1)) { lua_Integer new_score = lua_tointeger(L, -1); printf("Updated score in C: %lld\n", (long long)new_score); } lua_pop(L, 1); // Access the global table directly lua_pushglobaltable(L); lua_getfield(L, -1, "player_name"); printf("Player name from _G: %s\n", lua_tostring(L, -1)); lua_pop(L, 2); // Pop name and _G table } ``` -------------------------------- ### C: Build Loadable Lua Modules Source: https://context7.com/citizenfx/lua/llms.txt This C code illustrates how to create a loadable Lua module. It defines module functions for 'hello', 'add', and 'version', registers them using `luaL_newlib`, and provides the `luaopen_mylib` entry point. This allows Lua scripts to `require("mylib")` and use its functionalities. ```c #include "lua.h" #include "lauxlib.h" // Module functions static int mylib_hello(lua_State *L) { const char *name = luaL_optstring(L, 1, "World"); lua_pushfstring(L, "Hello, %s!", name); return 1; } static int mylib_add(lua_State *L) { lua_Number a = luaL_checknumber(L, 1); lua_Number b = luaL_checknumber(L, 2); lua_pushnumber(L, a + b); return 1; } static int mylib_version(lua_State *L) { lua_pushstring(L, "1.0.0"); return 1; } // Module registration function static const luaL_Reg mylib_functions[] = { {"hello", mylib_hello}, {"add", mylib_add}, {"version", mylib_version}, {NULL, NULL} // Sentinel }; // Module entry point (must be named luaopen_) int luaopen_mylib(lua_State *L) { // Create new library table luaL_newlib(L, mylib_functions); // Add some constants lua_pushinteger(L, 42); lua_setfield(L, -2, "MAGIC_NUMBER"); return 1; // Return the library table } // Usage in Lua after loading: // local mylib = require("mylib") // print(mylib.hello("Lua")) // print(mylib.add(10, 20)) // print(mylib.version()) // print(mylib.MAGIC_NUMBER) ``` -------------------------------- ### Create and Use Lua Tables from C Source: https://context7.com/citizenfx/lua/llms.txt Illustrates how to create, populate, and access Lua tables using the Lua C API. This includes setting string and integer keys, retrieving values by key, and iterating over table elements. ```c #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include void demonstrate_tables(lua_State *L) { // Create a new empty table lua_newtable(L); // table at top of stack // Set string keys (table[key] = value) lua_pushstring(L, "name"); lua_pushstring(L, "Alice"); lua_settable(L, -3); // Pops key and value // Convenient macro for string keys lua_pushstring(L, "Developer"); lua_setfield(L, -2, "role"); // table["role"] = "Developer" // Set integer keys (array-like) lua_pushinteger(L, 42); lua_seti(L, -2, 1); // table[1] = 42 lua_pushinteger(L, 99); lua_seti(L, -2, 2); // table[2] = 99 // Store table in global variable lua_setglobal(L, "person"); // Retrieve and read the table lua_getglobal(L, "person"); // Push table back // Get values by string key lua_getfield(L, -1, "name"); printf("Name: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); lua_getfield(L, -1, "role"); printf("Role: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); // Get values by integer key lua_geti(L, -1, 1); printf("Array[1]: %lld\n", (long long)lua_tointeger(L, -1)); lua_pop(L, 1); // Iterate over table lua_pushnil(L); // First key while (lua_next(L, -2) != 0) { // Key at -2, value at -1 printf("Key type: %s, ", lua_typename(L, lua_type(L, -2))); printf("Value: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); // Remove value, keep key for next iteration } lua_pop(L, 1); // Remove table } ``` -------------------------------- ### Create Simple Lua State and Execute String (C) Source: https://context7.com/citizenfx/lua/llms.txt Shows how to create a Lua state with default settings and execute a Lua script provided as a string. This is useful for simple, embedded scripting tasks. It initializes the Lua state, opens standard libraries, executes a 'print' command, and handles potential errors during execution. ```c #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include int main(void) { // Create new state with default allocator lua_State *L = luaL_newstate(); if (L == NULL) { fprintf(stderr, "Cannot create state\n"); return 1; } // Load all standard Lua libraries luaL_openlibs(L); // Execute a simple Lua string const char *script = "print('Hello from Lua!')"; if (luaL_dostring(L, script) != LUA_OK) { fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); lua_close(L); return 1; } lua_close(L); return 0; } ``` -------------------------------- ### Bash: Build Lua Interpreter and Library Source: https://context7.com/citizenfx/lua/llms.txt This bash script uses the 'make' utility to compile and link the Lua interpreter and its associated library. Running 'make all' is the standard command to build the entire Lua project. ```bash # Build everything make all ``` -------------------------------- ### Load and Execute Lua File with Error Handling (C) Source: https://context7.com/citizenfx/lua/llms.txt Provides C functions to load and execute Lua scripts from external files. It demonstrates using `luaL_loadfile` and `lua_pcall` for granular control and error reporting, as well as the simpler `luaL_dofile` macro. Proper error handling is included to report issues during loading or execution. ```c #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include int execute_lua_file(const char *filename) { lua_State *L = luaL_newstate(); if (L == NULL) return 1; luaL_openlibs(L); // Load file int status = luaL_loadfile(L, filename); if (status != LUA_OK) { fprintf(stderr, "Load error: %s\n", lua_tostring(L, -1)); lua_close(L); return 1; } // Execute loaded chunk with error handling status = lua_pcall(L, 0, LUA_MULTRET, 0); if (status != LUA_OK) { const char *error = lua_tostring(L, -1); fprintf(stderr, "Execution error: %s\n", error); lua_pop(L, 1); // Remove error message lua_close(L); return 1; } lua_close(L); return 0; } // Equivalent using macro int execute_lua_file_simple(const char *filename) { lua_State *L = luaL_newstate(); if (L == NULL) return 1; luaL_openlibs(L); // luaL_dofile is a macro that combines load and pcall if (luaL_dofile(L, filename) != LUA_OK) { fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); lua_close(L); return 1; } lua_close(L); return 0; } ``` -------------------------------- ### Manage Lua Coroutines from C Source: https://context7.com/citizenfx/lua/llms.txt Demonstrates how to create a Lua state, load a Lua function that uses coroutines, create a new Lua thread (coroutine) from C, and resume it multiple times, handling yielded values and errors. ```c #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include int coroutine_example(void) { lua_State *L = luaL_newstate(); if (L == NULL) return 1; luaL_openlibs(L); // Define a coroutine function const char *code = "function counter(start)\n" " local i = start\n" " while true do\n" " coroutine.yield(i)\n" " i = i + 1\n" " end\n" "end\n"; if (luaL_dostring(L, code) != LUA_OK) { fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); lua_close(L); return 1; } // Create a new thread (coroutine) lua_State *co = lua_newthread(L); // Load the function into the coroutine lua_getglobal(co, "counter"); lua_pushinteger(co, 100); // Resume the coroutine multiple times for (int i = 0; i < 5; i++) { int nres; int status = lua_resume(co, L, (i == 0) ? 1 : 0, &nres); if (status == LUA_YIELD) { // Coroutine yielded a value lua_Integer value = lua_tointeger(co, -1); printf("Yielded: %lld\n", (long long)value); lua_pop(co, nres); // Remove yielded values } else if (status == LUA_OK) { printf("Coroutine finished\n"); break; } else { fprintf(stderr, "Error: %s\n", lua_tostring(co, -1)); break; } } lua_close(L); return 0; } ``` -------------------------------- ### Call Lua Functions from C Source: https://context7.com/citizenfx/lua/llms.txt Demonstrates how to call a Lua function from C, passing arguments and retrieving multiple return values. Requires the Lua C API headers. ```c #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include int call_lua_function(void) { lua_State *L = luaL_newstate(); if (L == NULL) return 1; luaL_openlibs(L); // Define a Lua function const char *code = "function add(a, b)\n" " return a + b, a * b\n" // Multiple return values "end\n"; if (luaL_dostring(L, code) != LUA_OK) { fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); lua_close(L); return 1; } // Get the function lua_getglobal(L, "add"); if (!lua_isfunction(L, -1)) { fprintf(stderr, "Not a function\n"); lua_close(L); return 1; } // Push arguments lua_pushinteger(L, 10); lua_pushinteger(L, 20); // Call function: 2 args, 2 results, 0 = no error handler if (lua_pcall(L, 2, 2, 0) != LUA_OK) { fprintf(stderr, "Call error: %s\n", lua_tostring(L, -1)); lua_close(L); return 1; } // Get results (they're on the stack in order) lua_Integer sum = lua_tointeger(L, -2); lua_Integer product = lua_tointeger(L, -1); printf("Sum: %lld, Product: %lld\n", (long long)sum, (long long)product); lua_pop(L, 2); // Remove results lua_close(L); return 0; } ``` -------------------------------- ### Create Lua State with Custom Allocator (C) Source: https://context7.com/citizenfx/lua/llms.txt Demonstrates creating a new Lua state using a custom memory allocator function in C. This allows for fine-grained control over memory management during Lua state operations. It includes the necessary headers, the allocator function, and the main function to initialize and close the Lua state. ```c #include "lua.h" #include "lauxlib.h" #include "lualib.h" // Custom allocator function void* my_alloc(void *ud, void *ptr, size_t osize, size_t nsize) { (void)ud; (void)osize; // unused if (nsize == 0) { free(ptr); return NULL; } return realloc(ptr, nsize); } int main(void) { // Create new Lua state with custom allocator lua_State *L = lua_newstate(my_alloc, NULL); if (L == NULL) { fprintf(stderr, "Cannot create Lua state\n"); return 1; } // Open standard libraries luaL_openlibs(L); // Use the state... // Clean up lua_close(L); return 0; } ``` -------------------------------- ### Handle Lua Errors Gracefully with Protected Calls in C Source: https://context7.com/citizenfx/lua/llms.txt This C function demonstrates how to use `lua_pcall` to execute Lua code in a protected environment, allowing for graceful error handling. It includes a custom error handler function that adds a traceback to the error message. Dependencies include the Lua C API headers. ```c #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include // Error handler function static int error_handler(lua_State *L) { const char *msg = lua_tostring(L, -1); if (msg == NULL) msg = "(error object is not a string)"; // Add traceback luaL_traceback(L, L, msg, 1); return 1; } int protected_call_example(void) { lua_State *L = luaL_newstate(); if (L == NULL) return 1; luaL_openlibs(L); // Code that will cause an error const char *bad_code = "function risky_operation(x)\n" " if x < 0 then\n" " error('Negative value not allowed!')\n" " end\n" " return x * 2\n" "end\n"; if (luaL_dostring(L, bad_code) != LUA_OK) { fprintf(stderr, "Setup error: %s\n", lua_tostring(L, -1)); lua_close(L); return 1; } // Push error handler lua_pushcfunction(L, error_handler); int errfunc_idx = lua_gettop(L); // Get function lua_getglobal(L, "risky_operation"); // Push argument that will cause error lua_pushinteger(L, -5); // Protected call with error handler int status = lua_pcall(L, 1, 1, errfunc_idx); if (status != LUA_OK) { const char *error_msg = lua_tostring(L, -1); fprintf(stderr, "Protected call failed:\n%s\n", error_msg); lua_pop(L, 1); // Remove error message } else { lua_Integer result = lua_tointeger(L, -1); printf("Result: %lld\n", (long long)result); lua_pop(L, 1); } lua_pop(L, 1); // Remove error handler lua_close(L); return 0; } ``` -------------------------------- ### C: Create Custom Types with Userdata and Metatables Source: https://context7.com/citizenfx/lua/llms.txt This C code demonstrates how to create custom data types in Lua using userdata and metatables. It defines a 'Point' type with constructor and methods like 'distance' and 'move', and registers it for use within Lua scripts. Dependencies include the Lua C API headers. ```c #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include #include typedef struct { int x; int y; } Point; #define POINT_METATABLE "Point" // Constructor static int point_new(lua_State *L) { int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); // Allocate userdata Point *p = (Point *)lua_newuserdata(L, sizeof(Point)); p->x = x; p->y = y; // Set metatable luaL_setmetatable(L, POINT_METATABLE); return 1; } // Method: distance from origin static int point_distance(lua_State *L) { Point *p = (Point *)luaL_checkudata(L, 1, POINT_METATABLE); double dist = sqrt(p->x * p->x + p->y * p->y); lua_pushnumber(L, dist); return 1; } // Method: move point static int point_move(lua_State *L) { Point *p = (Point *)luaL_checkudata(L, 1, POINT_METATABLE); int dx = luaL_checkinteger(L, 2); int dy = luaL_checkinteger(L, 3); p->x += dx; p->y += dy; return 0; } // __tostring metamethod static int point_tostring(lua_State *L) { Point *p = (Point *)luaL_checkudata(L, 1, POINT_METATABLE); lua_pushfstring(L, "Point(%d, %d)", p->x, p->y); return 1; } // Register Point type void register_point_type(lua_State *L) { // Create metatable luaL_newmetatable(L, POINT_METATABLE); // Set __index to itself (methods lookup) lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); // Register methods static const luaL_Reg methods[] = { {"distance", point_distance}, {"move", point_move}, {NULL, NULL} }; luaL_setfuncs(L, methods, 0); // Register metamethods lua_pushcfunction(L, point_tostring); lua_setfield(L, -2, "__tostring"); lua_pop(L, 1); // Pop metatable // Register constructor lua_pushcfunction(L, point_new); lua_setglobal(L, "Point"); } int main(void) { lua_State *L = luaL_newstate(); if (L == NULL) return 1; luaL_openlibs(L); register_point_type(L); const char *test = "local p = Point(3, 4)\n" "print(p)\n" "print('Distance:', p:distance())\n" "p:move(1, 1)\n" "print('After move:', p)\n"; if (luaL_dostring(L, test) != LUA_OK) { fprintf(stderr, "Error: %s\n", lua_tostring(L, -1)); } lua_close(L); return 0; } ``` -------------------------------- ### C: Control Lua Garbage Collection Source: https://context7.com/citizenfx/lua/llms.txt This C code provides functions to control Lua's garbage collector. It demonstrates how to check memory usage, stop and restart the GC, force a collection cycle, and check if the GC is running, using the `lua_gc` function. ```c #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include void gc_example(lua_State *L) { // Get current memory usage (in Kbytes) int kb = lua_gc(L, LUA_GCCOUNT, 0); int bytes = lua_gc(L, LUA_GCCOUNTB, 0); printf("Memory usage: %d KB + %d bytes\n", kb, bytes); // Stop garbage collector lua_gc(L, LUA_GCSTOP, 0); printf("GC stopped\n"); // Create some garbage luaL_dostring(L, "t = {}; for i=1,1000 do t[i] = {x=i} end"); int kb2 = lua_gc(L, LUA_GCCOUNT, 0); printf("Memory after allocation: %d KB\n", kb2); // Restart garbage collector lua_gc(L, LUA_GCRESTART, 0); printf("GC restarted\n"); // Force a full garbage collection cycle lua_gc(L, LUA_GCCOLLECT, 0); printf("Full GC cycle completed\n"); int kb3 = lua_gc(L, LUA_GCCOUNT, 0); printf("Memory after GC: %d KB\n", kb3); // Check if GC is running int running = lua_gc(L, LUA_GCISRUNNING, 0); printf("GC is %s\n", running ? "running" : "stopped"); // Perform incremental GC step lua_gc(L, LUA_GCSTEP, 1); printf("Performed incremental GC step\n"); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.