It’s always something

The week of August 25th-30th earns a major black mark. Localization is just one of those things that shows everything bad and evil about Open Source Code. It’s one of those things where Microsoft has a clear and winning advantage because someone makes the call and bing all products comply with a single, standard, well defined interface for supporting languages.

I finally beat the code on 3 platforms into conformance; I spent today baby-stepping through migrating the MySQL databases to UTF8/UCS2 encoding/storage on the dev cluster and then validated it on the beta.

Wrote up my end of week report and decided to test something quick on the dev cluster. Odd. It’s not running, though.I quickly tracked the problem down to the strat host refusing to run. It works fine on the beta cluster, but for it simply fails to launch on dev. I fiddle around for a few minutes and try running it in a debugger. Can’t find “tolua++” library. What the hey? How was it working before then? Oh wait, it looks like “yum-updatesd” has pulled an adobe on me and has updated the packages on my build box. ARGH!

Ok, so I get the new tolua++ installed on the machines. Lets try again.

2008-08-30-03.26.46/strthost.0.log:A [Sat 8/30 03:20.59.756 rc.lua:0] file: /playnet/lua/rc.lua:6: attempt to call global ‘require’ (a nil value)

Erh. That’s like a basic, fundamental function isn’t it? Oh, ok, it’s been moved to the “package” library, apparently I need to load that. I look up the list of luaopen_base(vm) etc, and add luaopen_package(vm). I try to start the host, it exits.

PANIC: unprotected error in call to Lua API (no calling environment)

What? Ok, a little pootling around in the manual says something about having to call them like Lua functions. Uh… What?

Google to the rescue:

According to the the 5.1 reference manual, you can’t call the luaopen_*

funtions directly, but have to call them like a lua function. I’m sure the

rest will fall in place from there.

Rooting around, I find a piece of advice to call “luaL_openlibs(vm)”. Ok, I take out my specific openlibs and call that. The host crashes with a bizzare and cryptic error. A whole bunch of googling reveals that luaL_openlibs is trying to open the io library which, apparently, isn’t supported. Excellent.

More googling leads only to the crappy and typically open source piece of advice:

“The luaopen_* functions (to open libraries) cannot be called directly, like a regular C function. They must be called through Lua, like a Lua function” i.e. try lua_call() See linit.c for an example.

I.e. “read this other piece of code”. Ok, well, linit.c looks like this:

** $Id: linit.c,v 1.14 2005/12/29 15:32:11 roberto Exp $
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h

#define linit_c
#define LUA_LIB

#include “lua.h”

#include “lualib.h”
#include “lauxlib.h”

static const luaL_Reg lualibs[] = {
{“”, luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},

LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib = lualibs;
for (; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_pushstring(L, lib->name);
lua_call(L, 1, 0);

Since the IO and OS libs seem to cause it to crash, I add this to my own “luaGlue.cpp”:

static void
_luaOpenLib(lua_State* L, const char* name, lua_CFunction fn)
    lua_pushcfunction(L, fn) ;
    lua_pushstring(L, name) ;
    lua_call(L, 1, 0) ;
static void
_luaOpenLibs(lua_State* L)
    _luaOpenLib(L, “”, luaopen_base) ;
    _luaOpenLib(L, LUA_LOADLIBNAME, luaopen_package) ;
    _luaOpenLib(L, LUA_TABLIBNAME, luaopen_table) ;
    _luaOpenLib(L, LUA_STRLIBNAME, luaopen_string) ;
    _luaOpenLib(L, LUA_MATHLIBNAME, luaopen_math) ;

Compile, push, boot…

I [Sat 8/30 04:12.39.610 wwiiIRC.cpp:432] IRC e:num#366 p:3[^DevStrat|#servers|End of /NAMES list.]
I [Sat 8/30 04:12.39.610 wwiiIRC.cpp:640] IRC: Joined #servers
I [Sat 8/30 04:12.39.610 luaGlue.cpp:271] started Lua interpreter
A [Sat 8/30 04:12.39.610 rc.lua:0] file: /playnet/lua/rc.lua:4: module ‘/playnet/lua/cpevents’ not found:
no field package.preload[‘/playnet/lua/cpevents’]
no file ‘.//playnet/lua/cpevents.lua’
no file ‘/usr/share/lua/5.1//playnet/lua/cpevents.lua’
no file ‘/usr/share/lua/5.1//playnet/lua/cpevents/init.lua’
no file ‘/usr/lib/lua/5.1//playnet/lua/cpevents.lua’
no file ‘/usr/lib/lua/5.1//playnet/lua/cpevents/init.lua’
no file ‘.//playnet/lua/’
no file ‘/usr/lib/lua/5.1//playnet/lua/’
no file ‘/usr/lib/lua/5.1/’
W [Sat 8/30 04:12.39.610 luaGlue.cpp:280] startup file failed
I [Sat 8/30 04:12.39.610 wwiiIRC.cpp:432] IRC e:ERROR o:NULL p:1[Closing Link: (Quit: Shutdown [cleanly])]

ARGH. Apparently, either Lua or whomever is building the Lua modules had decided that absolute paths are bad. This one takes a lot of hunting because what Lua documentation there is contains marvelous gems like the following:

However, ANSI C (the abstract platform where Lua runs) does not have the concept of directories.

It’s 3am and I’m being blocked at every turn, so that simple slip of the keyboard derailed me for a good while. I went off trying to figure out how to make Lua understand directories again.

Ok, so it turns out there is a “LUA_PATH” environment variable I can use to specify my path. Deciding that maybe it is a bad idea I decided to make LUA_PATH a global environment variable for the server-process user and remove the explicit paths from the Lua scripts.

Finally, the host is running. I log in.

Uhm… What was I going to test?


You need to test your pillow and your bed. ;)

Hey, why I’m I seeing your job advertized on the site?

Dare we hope its for outplacement in China? Or that there can somehow magically be two lead server developers?

Maybe the ad is part of a process to show that no other applicants are fully qualified for your position, so that CRS/you can get special status to hold it, pending further changes to your immigration status?

Include these libraries in your build system, then you will not get a conflict between versions, api:s and you will have your own modifications in your own repository.

I don’t think that localisation in open source is so very bad. Pretty much all modern libraries handling strings works with UTF-8, translations can use gettext and if you use pango you will get a localized rendering engine too.

Leave a Reply

Name and email address are required. Your email address will not be published.

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

You may use these HTML tags and attributes:

<a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <pre> <q cite=""> <s> <strike> <strong> 

%d bloggers like this: