Reading A Lua Configuration File From C
Contents
Introduction
Lua is a scripting language that is embeddable in C/C++ programs. With Lua's C API, you can use a Lua file to configure your program settings.
Take for example the following Lua file that could serve as the configuration for a computer game. It specifies the screen resolution and the locations of images.
settings = { resolution = { width = 800, height = 600, fullscreen = true }, images = { "C:\\apple.bmp", "C:\\banana.bmp", "C:\\carrot.bmp" } }It's easy to access the data from Lua:
print( settings.resolution.width ) -- prints 800 print( settings.resolution.fullscreen ) -- prints true print( settings.images[ 1 ] ) -- prints C:\apple.bmp
It takes a bit more work to access the same data from a C program.
Although Lua's C API provides a lua_getglobal
function for accessing global variables,
there are no functions for easily accessing nested variables.
In this tutorial I will describe a few C functions that I created to accomplish this. They can be downloaded at the end of the tutorial. The functions have been tested with version 5.1 of Lua.
Using The Functions
The following table lists the functions I've written.
Function | Description |
---|---|
lua_stringexpr | Evaluates a Lua expression that returns a string. |
lua_numberexpr | Evaluates a Lua expression that returns a number. |
lua_intexpr | Evaluates a Lua expression that returns an integer. |
lua_boolexpr | Evaluates a Lua expression that returns a bool. |
The print_settings
function below shows how to use the functions. Assume that the lua_State
that is passed into print_settings
has been initialized with the Lua settings
above using luaL_dofile
.
void print_settings( lua_State* L ) { const char* width = 0 ; int height = -1 ; int fullscreen = -1 ; int image_count = -1 ; int i = 0 ; /* Read resolution settings */ width = lua_stringexpr( L, "settings.resolution.width", 0 ); lua_intexpr( L, "settings.resolution.height", &height ) ; fullscreen = lua_boolexpr( L, "settings.resolution.fullscreen" ); /* Print resolution settings */ printf( "settings.resolution.width = %s\n", width ); printf( "settings.resolution.height = %d\n", height ); printf( "settings.resolution.fullscreen = %s\n",fullscreen ? "true":"false" ); /* Read the number of images */ lua_intexpr( L, "#settings.images", &image_count ) ; /* Print the image file paths. */ for ( i=0; i<image_count; ++i ) { const char* image ; char expr[64] = "" ; sprintf( expr, "settings.images[%d]", i+1 ); image = lua_stringexpr( L, expr, 0 ); printf( "settings.images[%d] = %s\n", i, image ); } }
Here's the output after calling print_settings
:
settings.resolution.width = 800 settings.resolution.height = 600 settings.resolution.fullscreen = true settings.images[1] = C:\apple.bmp settings.images[2] = C:\banana.bmp settings.images[3] = C:\carrot.bmp
How It Works
The C functions work by assigning a given Lua expression to a
global Lua variable. For example, if the expression is settings.resolution.width
,
the following is added into the Lua state:
evalExpr = settings.resolution.width
The global variable evalExpr
is then accessed from C using
lua_getglobal
.
The following is the source code for the lua_stringexpr
function.
All of the other functions are similarly defined.
/** Evaluates a Lua expression and returns the string result. If an error occurs or the result is not string, def is returned. */ const char* lua_stringexpr( lua_State* L, const char* expr, const char* def ) { const char* r = def ; char buf[256] = "" ; /* Assign the Lua expression to a Lua global variable. */ sprintf( buf, "evalExpr=%s", expr ); if ( !luaL_dostring( L, buf ) ) { /* Get the value of the global varibable */ lua_getglobal( L, "evalExpr" ); if ( lua_isstring( L, -1 ) ) { r = lua_tostring( L, -1 ); } /* remove lua_getglobal value */ lua_pop( L, 1 ); } return r ; }
Downloads
File | Description |
---|---|
lua-config-file.zip | The functions are defined in luautils.h and luautils.c. A sample program (main.c) and a Code::Blocks project are included. |