-+
-+
-+#include "llimits.h"
-+#include "lua.h"
-+
-+
-+/* tags for values visible from Lua */
-+#define LAST_TAG LUA_TTHREAD
-+
-+#define NUM_TAGS (LAST_TAG+1)
-+
-+
-+/*
-+** Extra tags for non-values
-+*/
-+#define LUA_TPROTO (LAST_TAG+1)
-+#define LUA_TUPVAL (LAST_TAG+2)
-+#define LUA_TDEADKEY (LAST_TAG+3)
-+
-+
-+/*
-+** Union of all collectable objects
-+*/
-+typedef union GCObject GCObject;
-+
-+
-+/*
-+** Common Header for all collectable objects (in macro form, to be
-+** included in other objects)
-+*/
-+#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
-+
-+
-+/*
-+** Common header in struct form
-+*/
-+typedef struct GCheader {
-+ CommonHeader;
-+} GCheader;
-+
-+
-+
-+
-+/*
-+** Union of all Lua values
-+*/
-+typedef union {
-+ GCObject *gc;
-+ void *p;
-+ lua_Number n;
-+ int b;
-+} Value;
-+
-+
-+/*
-+** Tagged Values
-+*/
-+
-+#define TValuefields Value value; int tt
-+
-+typedef struct lua_TValue {
-+ TValuefields;
-+} TValue;
-+
-+
-+/* Macros to test type */
-+#define ttisnil(o) (ttype(o) == LUA_TNIL)
-+#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
-+#define ttisstring(o) (ttype(o) == LUA_TSTRING)
-+#define ttistable(o) (ttype(o) == LUA_TTABLE)
-+#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
-+#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
-+#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
-+#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
-+#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
-+
-+/* Macros to access values */
-+#define ttype(o) ((o)->tt)
-+#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
-+#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
-+#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
-+#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
-+#define tsvalue(o) (&rawtsvalue(o)->tsv)
-+#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
-+#define uvalue(o) (&rawuvalue(o)->uv)
-+#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
-+#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
-+#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
-+#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
-+
-+#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
-+
-+/*
-+** for internal debug only
-+*/
-+#define checkconsistency(obj) \
-+ lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
-+
-+#define checkliveness(g,obj) \
-+ lua_assert(!iscollectable(obj) || \
-+ ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
-+
-+
-+/* Macros to set values */
-+#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
-+
-+#define setnvalue(obj,x) \
-+ { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
-+
-+#define setpvalue(obj,x) \
-+ { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
-+
-+#define setbvalue(obj,x) \
-+ { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
-+
-+#define setsvalue(L,obj,x) \
-+ { TValue *i_o=(obj); \
-+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
-+ checkliveness(G(L),i_o); }
-+
-+#define setuvalue(L,obj,x) \
-+ { TValue *i_o=(obj); \
-+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
-+ checkliveness(G(L),i_o); }
-+
-+#define setthvalue(L,obj,x) \
-+ { TValue *i_o=(obj); \
-+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
-+ checkliveness(G(L),i_o); }
-+
-+#define setclvalue(L,obj,x) \
-+ { TValue *i_o=(obj); \
-+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
-+ checkliveness(G(L),i_o); }
-+
-+#define sethvalue(L,obj,x) \
-+ { TValue *i_o=(obj); \
-+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
-+ checkliveness(G(L),i_o); }
-+
-+#define setptvalue(L,obj,x) \
-+ { TValue *i_o=(obj); \
-+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
-+ checkliveness(G(L),i_o); }
-+
-+
-+
-+
-+#define setobj(L,obj1,obj2) \
-+ { const TValue *o2=(obj2); TValue *o1=(obj1); \
-+ o1->value = o2->value; o1->tt=o2->tt; \
-+ checkliveness(G(L),o1); }
-+
-+
-+/*
-+** different types of sets, according to destination
-+*/
-+
-+/* from stack to (same) stack */
-+#define setobjs2s setobj
-+/* to stack (not from same stack) */
-+#define setobj2s setobj
-+#define setsvalue2s setsvalue
-+#define sethvalue2s sethvalue
-+#define setptvalue2s setptvalue
-+/* from table to same table */
-+#define setobjt2t setobj
-+/* to table */
-+#define setobj2t setobj
-+/* to new object */
-+#define setobj2n setobj
-+#define setsvalue2n setsvalue
-+
-+#define setttype(obj, tt) (ttype(obj) = (tt))
-+
-+
-+#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
-+
-+
-+
-+typedef TValue *StkId; /* index to stack elements */
-+
-+
-+/*
-+** String headers for string table
-+*/
-+typedef union TString {
-+ L_Umaxalign dummy; /* ensures maximum alignment for strings */
-+ struct {
-+ CommonHeader;
-+ lu_byte reserved;
-+ unsigned int hash;
-+ size_t len;
-+ } tsv;
-+} TString;
-+
-+
-+#define getstr(ts) cast(const char *, (ts) + 1)
-+#define svalue(o) getstr(rawtsvalue(o))
-+
-+
-+
-+typedef union Udata {
-+ L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
-+ struct {
-+ CommonHeader;
-+ struct Table *metatable;
-+ struct Table *env;
-+ size_t len;
-+ } uv;
-+} Udata;
-+
-+
-+
-+
-+/*
-+** Function Prototypes
-+*/
-+typedef struct Proto {
-+ CommonHeader;
-+ TValue *k; /* constants used by the function */
-+ Instruction *code;
-+ struct Proto **p; /* functions defined inside the function */
-+ int *lineinfo; /* map from opcodes to source lines */
-+ struct LocVar *locvars; /* information about local variables */
-+ TString **upvalues; /* upvalue names */
-+ TString *source;
-+ int sizeupvalues;
-+ int sizek; /* size of `k' */
-+ int sizecode;
-+ int sizelineinfo;
-+ int sizep; /* size of `p' */
-+ int sizelocvars;
-+ int linedefined;
-+ int lastlinedefined;
-+ GCObject *gclist;
-+ lu_byte nups; /* number of upvalues */
-+ lu_byte numparams;
-+ lu_byte is_vararg;
-+ lu_byte maxstacksize;
-+} Proto;
-+
-+
-+/* masks for new-style vararg */
-+#define VARARG_HASARG 1
-+#define VARARG_ISVARARG 2
-+#define VARARG_NEEDSARG 4
-+
-+
-+typedef struct LocVar {
-+ TString *varname;
-+ int startpc; /* first point where variable is active */
-+ int endpc; /* first point where variable is dead */
-+} LocVar;
-+
-+
-+
-+/*
-+** Upvalues
-+*/
-+
-+typedef struct UpVal {
-+ CommonHeader;
-+ TValue *v; /* points to stack or to its own value */
-+ union {
-+ TValue value; /* the value (when closed) */
-+ struct { /* double linked list (when open) */
-+ struct UpVal *prev;
-+ struct UpVal *next;
-+ } l;
-+ } u;
-+} UpVal;
-+
-+
-+/*
-+** Closures
-+*/
-+
-+#define ClosureHeader \
-+ CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
-+ struct Table *env
-+
-+typedef struct CClosure {
-+ ClosureHeader;
-+ lua_CFunction f;
-+ TValue upvalue[1];
-+} CClosure;
-+
-+
-+typedef struct LClosure {
-+ ClosureHeader;
-+ struct Proto *p;
-+ UpVal *upvals[1];
-+} LClosure;
-+
-+
-+typedef union Closure {
-+ CClosure c;
-+ LClosure l;
-+} Closure;
-+
-+
-+#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
-+#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
-+
-+
-+/*
-+** Tables
-+*/
-+
-+typedef union TKey {
-+ struct {
-+ TValuefields;
-+ struct Node *next; /* for chaining */
-+ } nk;
-+ TValue tvk;
-+} TKey;
-+
-+
-+typedef struct Node {
-+ TValue i_val;
-+ TKey i_key;
-+} Node;
-+
-+
-+typedef struct Table {
-+ CommonHeader;
-+ lu_byte flags; /* 1<lsizenode))
-+
-+
-+#define luaO_nilobject (&luaO_nilobject_)
-+
-+LUAI_DATA const TValue luaO_nilobject_;
-+
-+#define ceillog2(x) (luaO_log2((x)-1) + 1)
-+
-+LUAI_FUNC int luaO_log2 (unsigned int x);
-+LUAI_FUNC int luaO_int2fb (unsigned int x);
-+LUAI_FUNC int luaO_fb2int (int x);
-+LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
-+LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
-+LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
-+ va_list argp);
-+LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
-+LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
-+
-+
-+#endif
-+
---- /dev/null
-+++ b/extensions/LUA/lua/lopcodes.c
-@@ -0,0 +1,102 @@
-+/*
-+** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
-+** See Copyright Notice in lua.h
-+*/
-+
-+
-+#define lopcodes_c
-+#define LUA_CORE
-+
-+
-+#include "lopcodes.h"
-+
-+
-+/* ORDER OP */
-+
-+const char *const luaP_opnames[NUM_OPCODES+1] = {
-+ "MOVE",
-+ "LOADK",
-+ "LOADBOOL",
-+ "LOADNIL",
-+ "GETUPVAL",
-+ "GETGLOBAL",
-+ "GETTABLE",
-+ "SETGLOBAL",
-+ "SETUPVAL",
-+ "SETTABLE",
-+ "NEWTABLE",
-+ "SELF",
-+ "ADD",
-+ "SUB",
-+ "MUL",
-+ "DIV",
-+ "MOD",
-+ "POW",
-+ "UNM",
-+ "NOT",
-+ "LEN",
-+ "CONCAT",
-+ "JMP",
-+ "EQ",
-+ "LT",
-+ "LE",
-+ "TEST",
-+ "TESTSET",
-+ "CALL",
-+ "TAILCALL",
-+ "RETURN",
-+ "FORLOOP",
-+ "FORPREP",
-+ "TFORLOOP",
-+ "SETLIST",
-+ "CLOSE",
-+ "CLOSURE",
-+ "VARARG",
-+ NULL
-+};
-+
-+
-+#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
-+
-+const lu_byte luaP_opmodes[NUM_OPCODES] = {
-+/* T A B C mode opcode */
-+ opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
-+ ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
-+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
-+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
-+ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
-+ ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
-+ ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
-+ ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
-+ ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
-+ ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
-+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
-+ ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
-+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
-+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
-+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
-+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
-+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
-+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
-+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
-+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
-+ ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
-+ ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
-+ ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
-+ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
-+ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
-+ ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
-+ ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
-+ ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
-+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
-+ ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
-+ ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
-+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
-+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
-+ ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
-+ ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
-+ ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
-+ ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
-+ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
-+};
-+
---- /dev/null
-+++ b/extensions/LUA/lua/lopcodes.h
-@@ -0,0 +1,268 @@
-+/*
-+** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $
-+** Opcodes for Lua virtual machine
-+** See Copyright Notice in lua.h
-+*/
-+
-+#ifndef lopcodes_h
-+#define lopcodes_h
-+
-+#include "llimits.h"
-+
-+
-+/*===========================================================================
-+ We assume that instructions are unsigned numbers.
-+ All instructions have an opcode in the first 6 bits.
-+ Instructions can have the following fields:
-+ `A' : 8 bits
-+ `B' : 9 bits
-+ `C' : 9 bits
-+ `Bx' : 18 bits (`B' and `C' together)
-+ `sBx' : signed Bx
-+
-+ A signed argument is represented in excess K; that is, the number
-+ value is the unsigned value minus K. K is exactly the maximum value
-+ for that argument (so that -max is represented by 0, and +max is
-+ represented by 2*max), which is half the maximum for the corresponding
-+ unsigned argument.
-+===========================================================================*/
-+
-+
-+enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
-+
-+
-+/*
-+** size and position of opcode arguments.
-+*/
-+#define SIZE_C 9
-+#define SIZE_B 9
-+#define SIZE_Bx (SIZE_C + SIZE_B)
-+#define SIZE_A 8
-+
-+#define SIZE_OP 6
-+
-+#define POS_OP 0
-+#define POS_A (POS_OP + SIZE_OP)
-+#define POS_C (POS_A + SIZE_A)
-+#define POS_B (POS_C + SIZE_C)
-+#define POS_Bx POS_C
-+
-+
-+/*
-+** limits for opcode arguments.
-+** we use (signed) int to manipulate most arguments,
-+** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
-+*/
-+#if SIZE_Bx < LUAI_BITSINT-1
-+#define MAXARG_Bx ((1<>1) /* `sBx' is signed */
-+#else
-+#define MAXARG_Bx MAX_INT
-+#define MAXARG_sBx MAX_INT
-+#endif
-+
-+
-+#define MAXARG_A ((1<>POS_OP) & MASK1(SIZE_OP,0)))
-+#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
-+ ((cast(Instruction, o)<>POS_A) & MASK1(SIZE_A,0)))
-+#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
-+ ((cast(Instruction, u)<>POS_B) & MASK1(SIZE_B,0)))
-+#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
-+ ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0)))
-+#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
-+ ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0)))
-+#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
-+ ((cast(Instruction, b)< C) then pc++ */
-+OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
-+
-+OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
-+OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
-+OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */
-+
-+OP_FORLOOP,/* A sBx R(A)+=R(A+2);
-+ if R(A) = R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
-+OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
-+
-+OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
-+ if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
-+OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
-+
-+OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
-+OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
-+
-+OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
-+} OpCode;
-+
-+
-+#define NUM_OPCODES (cast(int, OP_VARARG) + 1)
-+
-+
-+
-+/*===========================================================================
-+ Notes:
-+ (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
-+ and can be 0: OP_CALL then sets `top' to last_result+1, so
-+ next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
-+
-+ (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
-+ set top (like in OP_CALL with C == 0).
-+
-+ (*) In OP_RETURN, if (B == 0) then return up to `top'
-+
-+ (*) In OP_SETLIST, if (B == 0) then B = `top';
-+ if (C == 0) then next `instruction' is real C
-+
-+ (*) For comparisons, A specifies what condition the test should accept
-+ (true or false).
-+
-+ (*) All `skips' (pc++) assume that next instruction is a jump
-+===========================================================================*/
-+
-+
-+/*
-+** masks for instruction properties. The format is:
-+** bits 0-1: op mode
-+** bits 2-3: C arg mode
-+** bits 4-5: B arg mode
-+** bit 6: instruction set register A
-+** bit 7: operator is a test
-+*/
-+
-+enum OpArgMask {
-+ OpArgN, /* argument is not used */
-+ OpArgU, /* argument is used */
-+ OpArgR, /* argument is a register or a jump offset */
-+ OpArgK /* argument is a constant or register/constant */
-+};
-+
-+LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
-+
-+#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
-+#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
-+#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3))
-+#define testAMode(m) (luaP_opmodes[m] & (1 << 6))
-+#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
-+
-+
-+LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
-+
-+
-+/* number of list items to accumulate before a SETLIST instruction */
-+#define LFIELDS_PER_FLUSH 50
-+
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/lua/lparser.c
-@@ -0,0 +1,1339 @@
-+/*
-+** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $
-+** Lua Parser
-+** See Copyright Notice in lua.h
-+*/
-+
-+
-+#include
-+
-+#define lparser_c
-+#define LUA_CORE
-+
-+#include "lua.h"
-+
-+#include "lcode.h"
-+#include "ldebug.h"
-+#include "ldo.h"
-+#include "lfunc.h"
-+#include "llex.h"
-+#include "lmem.h"
-+#include "lobject.h"
-+#include "lopcodes.h"
-+#include "lparser.h"
-+#include "lstate.h"
-+#include "lstring.h"
-+#include "ltable.h"
-+
-+
-+
-+#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
-+
-+#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
-+
-+#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
-+
-+
-+/*
-+** nodes for block list (list of active blocks)
-+*/
-+typedef struct BlockCnt {
-+ struct BlockCnt *previous; /* chain */
-+ int breaklist; /* list of jumps out of this loop */
-+ lu_byte nactvar; /* # active locals outside the breakable structure */
-+ lu_byte upval; /* true if some variable in the block is an upvalue */
-+ lu_byte isbreakable; /* true if `block' is a loop */
-+} BlockCnt;
-+
-+
-+
-+/*
-+** prototypes for recursive non-terminal functions
-+*/
-+static void chunk (LexState *ls);
-+static void expr (LexState *ls, expdesc *v);
-+
-+
-+static void anchor_token (LexState *ls) {
-+ if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
-+ TString *ts = ls->t.seminfo.ts;
-+ luaX_newstring(ls, getstr(ts), ts->tsv.len);
-+ }
-+}
-+
-+
-+static void error_expected (LexState *ls, int token) {
-+ luaX_syntaxerror(ls,
-+ luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token)));
-+}
-+
-+
-+static void errorlimit (FuncState *fs, int limit, const char *what) {
-+ const char *msg = (fs->f->linedefined == 0) ?
-+ luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
-+ luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
-+ fs->f->linedefined, limit, what);
-+ luaX_lexerror(fs->ls, msg, 0);
-+}
-+
-+
-+static int testnext (LexState *ls, int c) {
-+ if (ls->t.token == c) {
-+ luaX_next(ls);
-+ return 1;
-+ }
-+ else return 0;
-+}
-+
-+
-+static void check (LexState *ls, int c) {
-+ if (ls->t.token != c)
-+ error_expected(ls, c);
-+}
-+
-+static void checknext (LexState *ls, int c) {
-+ check(ls, c);
-+ luaX_next(ls);
-+}
-+
-+
-+#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }
-+
-+
-+
-+static void check_match (LexState *ls, int what, int who, int where) {
-+ if (!testnext(ls, what)) {
-+ if (where == ls->linenumber)
-+ error_expected(ls, what);
-+ else {
-+ luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
-+ LUA_QS " expected (to close " LUA_QS " at line %d)",
-+ luaX_token2str(ls, what), luaX_token2str(ls, who), where));
-+ }
-+ }
-+}
-+
-+
-+static TString *str_checkname (LexState *ls) {
-+ TString *ts;
-+ check(ls, TK_NAME);
-+ ts = ls->t.seminfo.ts;
-+ luaX_next(ls);
-+ return ts;
-+}
-+
-+
-+static void init_exp (expdesc *e, expkind k, int i) {
-+ e->f = e->t = NO_JUMP;
-+ e->k = k;
-+ e->u.s.info = i;
-+}
-+
-+
-+static void codestring (LexState *ls, expdesc *e, TString *s) {
-+ init_exp(e, VK, luaK_stringK(ls->fs, s));
-+}
-+
-+
-+static void checkname(LexState *ls, expdesc *e) {
-+ codestring(ls, e, str_checkname(ls));
-+}
-+
-+
-+static int registerlocalvar (LexState *ls, TString *varname) {
-+ FuncState *fs = ls->fs;
-+ Proto *f = fs->f;
-+ int oldsize = f->sizelocvars;
-+ luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
-+ LocVar, SHRT_MAX, "too many local variables");
-+ while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
-+ f->locvars[fs->nlocvars].varname = varname;
-+ luaC_objbarrier(ls->L, f, varname);
-+ return fs->nlocvars++;
-+}
-+
-+
-+#define new_localvarliteral(ls,v,n) \
-+ new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)
-+
-+
-+static void new_localvar (LexState *ls, TString *name, int n) {
-+ FuncState *fs = ls->fs;
-+ luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
-+ fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
-+}
-+
-+
-+static void adjustlocalvars (LexState *ls, int nvars) {
-+ FuncState *fs = ls->fs;
-+ fs->nactvar = cast_byte(fs->nactvar + nvars);
-+ for (; nvars; nvars--) {
-+ getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
-+ }
-+}
-+
-+
-+static void removevars (LexState *ls, int tolevel) {
-+ FuncState *fs = ls->fs;
-+ while (fs->nactvar > tolevel)
-+ getlocvar(fs, --fs->nactvar).endpc = fs->pc;
-+}
-+
-+
-+static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
-+ int i;
-+ Proto *f = fs->f;
-+ int oldsize = f->sizeupvalues;
-+ for (i=0; inups; i++) {
-+ if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) {
-+ lua_assert(f->upvalues[i] == name);
-+ return i;
-+ }
-+ }
-+ /* new one */
-+ luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
-+ luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
-+ TString *, MAX_INT, "");
-+ while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
-+ f->upvalues[f->nups] = name;
-+ luaC_objbarrier(fs->L, f, name);
-+ lua_assert(v->k == VLOCAL || v->k == VUPVAL);
-+ fs->upvalues[f->nups].k = cast_byte(v->k);
-+ fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
-+ return f->nups++;
-+}
-+
-+
-+static int searchvar (FuncState *fs, TString *n) {
-+ int i;
-+ for (i=fs->nactvar-1; i >= 0; i--) {
-+ if (n == getlocvar(fs, i).varname)
-+ return i;
-+ }
-+ return -1; /* not found */
-+}
-+
-+
-+static void markupval (FuncState *fs, int level) {
-+ BlockCnt *bl = fs->bl;
-+ while (bl && bl->nactvar > level) bl = bl->previous;
-+ if (bl) bl->upval = 1;
-+}
-+
-+
-+static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
-+ if (fs == NULL) { /* no more levels? */
-+ init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
-+ return VGLOBAL;
-+ }
-+ else {
-+ int v = searchvar(fs, n); /* look up at current level */
-+ if (v >= 0) {
-+ init_exp(var, VLOCAL, v);
-+ if (!base)
-+ markupval(fs, v); /* local will be used as an upval */
-+ return VLOCAL;
-+ }
-+ else { /* not found at current level; try upper one */
-+ if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
-+ return VGLOBAL;
-+ var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
-+ var->k = VUPVAL; /* upvalue in this level */
-+ return VUPVAL;
-+ }
-+ }
-+}
-+
-+
-+static void singlevar (LexState *ls, expdesc *var) {
-+ TString *varname = str_checkname(ls);
-+ FuncState *fs = ls->fs;
-+ if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
-+ var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
-+}
-+
-+
-+static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
-+ FuncState *fs = ls->fs;
-+ int extra = nvars - nexps;
-+ if (hasmultret(e->k)) {
-+ extra++; /* includes call itself */
-+ if (extra < 0) extra = 0;
-+ luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
-+ if (extra > 1) luaK_reserveregs(fs, extra-1);
-+ }
-+ else {
-+ if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
-+ if (extra > 0) {
-+ int reg = fs->freereg;
-+ luaK_reserveregs(fs, extra);
-+ luaK_nil(fs, reg, extra);
-+ }
-+ }
-+}
-+
-+
-+static void enterlevel (LexState *ls) {
-+ if (++ls->L->nCcalls > LUAI_MAXCCALLS)
-+ luaX_lexerror(ls, "chunk has too many syntax levels", 0);
-+}
-+
-+
-+#define leavelevel(ls) ((ls)->L->nCcalls--)
-+
-+
-+static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
-+ bl->breaklist = NO_JUMP;
-+ bl->isbreakable = isbreakable;
-+ bl->nactvar = fs->nactvar;
-+ bl->upval = 0;
-+ bl->previous = fs->bl;
-+ fs->bl = bl;
-+ lua_assert(fs->freereg == fs->nactvar);
-+}
-+
-+
-+static void leaveblock (FuncState *fs) {
-+ BlockCnt *bl = fs->bl;
-+ fs->bl = bl->previous;
-+ removevars(fs->ls, bl->nactvar);
-+ if (bl->upval)
-+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
-+ /* a block either controls scope or breaks (never both) */
-+ lua_assert(!bl->isbreakable || !bl->upval);
-+ lua_assert(bl->nactvar == fs->nactvar);
-+ fs->freereg = fs->nactvar; /* free registers */
-+ luaK_patchtohere(fs, bl->breaklist);
-+}
-+
-+
-+static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
-+ FuncState *fs = ls->fs;
-+ Proto *f = fs->f;
-+ int oldsize = f->sizep;
-+ int i;
-+ luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
-+ MAXARG_Bx, "constant table overflow");
-+ while (oldsize < f->sizep) f->p[oldsize++] = NULL;
-+ f->p[fs->np++] = func->f;
-+ luaC_objbarrier(ls->L, f, func->f);
-+ init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
-+ for (i=0; if->nups; i++) {
-+ OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
-+ luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
-+ }
-+}
-+
-+
-+static void open_func (LexState *ls, FuncState *fs) {
-+ lua_State *L = ls->L;
-+ Proto *f = luaF_newproto(L);
-+ fs->f = f;
-+ fs->prev = ls->fs; /* linked list of funcstates */
-+ fs->ls = ls;
-+ fs->L = L;
-+ ls->fs = fs;
-+ fs->pc = 0;
-+ fs->lasttarget = -1;
-+ fs->jpc = NO_JUMP;
-+ fs->freereg = 0;
-+ fs->nk = 0;
-+ fs->np = 0;
-+ fs->nlocvars = 0;
-+ fs->nactvar = 0;
-+ fs->bl = NULL;
-+ f->source = ls->source;
-+ f->maxstacksize = 2; /* registers 0/1 are always valid */
-+ fs->h = luaH_new(L, 0, 0);
-+ /* anchor table of constants and prototype (to avoid being collected) */
-+ sethvalue2s(L, L->top, fs->h);
-+ incr_top(L);
-+ setptvalue2s(L, L->top, f);
-+ incr_top(L);
-+}
-+
-+
-+static void close_func (LexState *ls) {
-+ lua_State *L = ls->L;
-+ FuncState *fs = ls->fs;
-+ Proto *f = fs->f;
-+ removevars(ls, 0);
-+ luaK_ret(fs, 0, 0); /* final return */
-+ luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
-+ f->sizecode = fs->pc;
-+ luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
-+ f->sizelineinfo = fs->pc;
-+ luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
-+ f->sizek = fs->nk;
-+ luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
-+ f->sizep = fs->np;
-+ luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
-+ f->sizelocvars = fs->nlocvars;
-+ luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
-+ f->sizeupvalues = f->nups;
-+ lua_assert(luaG_checkcode(f));
-+ lua_assert(fs->bl == NULL);
-+ ls->fs = fs->prev;
-+ L->top -= 2; /* remove table and prototype from the stack */
-+ /* last token read was anchored in defunct function; must reanchor it */
-+ if (fs) anchor_token(ls);
-+}
-+
-+
-+Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
-+ struct LexState lexstate;
-+ struct FuncState funcstate;
-+ lexstate.buff = buff;
-+ luaX_setinput(L, &lexstate, z, luaS_new(L, name));
-+ open_func(&lexstate, &funcstate);
-+ funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
-+ luaX_next(&lexstate); /* read first token */
-+ chunk(&lexstate);
-+ check(&lexstate, TK_EOS);
-+ close_func(&lexstate);
-+ lua_assert(funcstate.prev == NULL);
-+ lua_assert(funcstate.f->nups == 0);
-+ lua_assert(lexstate.fs == NULL);
-+ return funcstate.f;
-+}
-+
-+
-+
-+/*============================================================*/
-+/* GRAMMAR RULES */
-+/*============================================================*/
-+
-+
-+static void field (LexState *ls, expdesc *v) {
-+ /* field -> ['.' | ':'] NAME */
-+ FuncState *fs = ls->fs;
-+ expdesc key;
-+ luaK_exp2anyreg(fs, v);
-+ luaX_next(ls); /* skip the dot or colon */
-+ checkname(ls, &key);
-+ luaK_indexed(fs, v, &key);
-+}
-+
-+
-+static void yindex (LexState *ls, expdesc *v) {
-+ /* index -> '[' expr ']' */
-+ luaX_next(ls); /* skip the '[' */
-+ expr(ls, v);
-+ luaK_exp2val(ls->fs, v);
-+ checknext(ls, ']');
-+}
-+
-+
-+/*
-+** {======================================================================
-+** Rules for Constructors
-+** =======================================================================
-+*/
-+
-+
-+struct ConsControl {
-+ expdesc v; /* last list item read */
-+ expdesc *t; /* table descriptor */
-+ int nh; /* total number of `record' elements */
-+ int na; /* total number of array elements */
-+ int tostore; /* number of array elements pending to be stored */
-+};
-+
-+
-+static void recfield (LexState *ls, struct ConsControl *cc) {
-+ /* recfield -> (NAME | `['exp1`]') = exp1 */
-+ FuncState *fs = ls->fs;
-+ int reg = ls->fs->freereg;
-+ expdesc key, val;
-+ int rkkey;
-+ if (ls->t.token == TK_NAME) {
-+ luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
-+ checkname(ls, &key);
-+ }
-+ else /* ls->t.token == '[' */
-+ yindex(ls, &key);
-+ cc->nh++;
-+ checknext(ls, '=');
-+ rkkey = luaK_exp2RK(fs, &key);
-+ expr(ls, &val);
-+ luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));
-+ fs->freereg = reg; /* free registers */
-+}
-+
-+
-+static void closelistfield (FuncState *fs, struct ConsControl *cc) {
-+ if (cc->v.k == VVOID) return; /* there is no list item */
-+ luaK_exp2nextreg(fs, &cc->v);
-+ cc->v.k = VVOID;
-+ if (cc->tostore == LFIELDS_PER_FLUSH) {
-+ luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */
-+ cc->tostore = 0; /* no more items pending */
-+ }
-+}
-+
-+
-+static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
-+ if (cc->tostore == 0) return;
-+ if (hasmultret(cc->v.k)) {
-+ luaK_setmultret(fs, &cc->v);
-+ luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET);
-+ cc->na--; /* do not count last expression (unknown number of elements) */
-+ }
-+ else {
-+ if (cc->v.k != VVOID)
-+ luaK_exp2nextreg(fs, &cc->v);
-+ luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);
-+ }
-+}
-+
-+
-+static void listfield (LexState *ls, struct ConsControl *cc) {
-+ expr(ls, &cc->v);
-+ luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
-+ cc->na++;
-+ cc->tostore++;
-+}
-+
-+
-+static void constructor (LexState *ls, expdesc *t) {
-+ /* constructor -> ?? */
-+ FuncState *fs = ls->fs;
-+ int line = ls->linenumber;
-+ int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
-+ struct ConsControl cc;
-+ cc.na = cc.nh = cc.tostore = 0;
-+ cc.t = t;
-+ init_exp(t, VRELOCABLE, pc);
-+ init_exp(&cc.v, VVOID, 0); /* no value (yet) */
-+ luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
-+ checknext(ls, '{');
-+ do {
-+ lua_assert(cc.v.k == VVOID || cc.tostore > 0);
-+ if (ls->t.token == '}') break;
-+ closelistfield(fs, &cc);
-+ switch(ls->t.token) {
-+ case TK_NAME: { /* may be listfields or recfields */
-+ luaX_lookahead(ls);
-+ if (ls->lookahead.token != '=') /* expression? */
-+ listfield(ls, &cc);
-+ else
-+ recfield(ls, &cc);
-+ break;
-+ }
-+ case '[': { /* constructor_item -> recfield */
-+ recfield(ls, &cc);
-+ break;
-+ }
-+ default: { /* constructor_part -> listfield */
-+ listfield(ls, &cc);
-+ break;
-+ }
-+ }
-+ } while (testnext(ls, ',') || testnext(ls, ';'));
-+ check_match(ls, '}', '{', line);
-+ lastlistfield(fs, &cc);
-+ SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
-+ SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
-+}
-+
-+/* }====================================================================== */
-+
-+
-+
-+static void parlist (LexState *ls) {
-+ /* parlist -> [ param { `,' param } ] */
-+ FuncState *fs = ls->fs;
-+ Proto *f = fs->f;
-+ int nparams = 0;
-+ f->is_vararg = 0;
-+ if (ls->t.token != ')') { /* is `parlist' not empty? */
-+ do {
-+ switch (ls->t.token) {
-+ case TK_NAME: { /* param -> NAME */
-+ new_localvar(ls, str_checkname(ls), nparams++);
-+ break;
-+ }
-+ case TK_DOTS: { /* param -> `...' */
-+ luaX_next(ls);
-+#if defined(LUA_COMPAT_VARARG)
-+ /* use `arg' as default name */
-+ new_localvarliteral(ls, "arg", nparams++);
-+ f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
-+#endif
-+ f->is_vararg |= VARARG_ISVARARG;
-+ break;
-+ }
-+ default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected");
-+ }
-+ } while (!f->is_vararg && testnext(ls, ','));
-+ }
-+ adjustlocalvars(ls, nparams);
-+ f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
-+ luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
-+}
-+
-+
-+static void body (LexState *ls, expdesc *e, int needself, int line) {
-+ /* body -> `(' parlist `)' chunk END */
-+ FuncState new_fs;
-+ open_func(ls, &new_fs);
-+ new_fs.f->linedefined = line;
-+ checknext(ls, '(');
-+ if (needself) {
-+ new_localvarliteral(ls, "self", 0);
-+ adjustlocalvars(ls, 1);
-+ }
-+ parlist(ls);
-+ checknext(ls, ')');
-+ chunk(ls);
-+ new_fs.f->lastlinedefined = ls->linenumber;
-+ check_match(ls, TK_END, TK_FUNCTION, line);
-+ close_func(ls);
-+ pushclosure(ls, &new_fs, e);
-+}
-+
-+
-+static int explist1 (LexState *ls, expdesc *v) {
-+ /* explist1 -> expr { `,' expr } */
-+ int n = 1; /* at least one expression */
-+ expr(ls, v);
-+ while (testnext(ls, ',')) {
-+ luaK_exp2nextreg(ls->fs, v);
-+ expr(ls, v);
-+ n++;
-+ }
-+ return n;
-+}
-+
-+
-+static void funcargs (LexState *ls, expdesc *f) {
-+ FuncState *fs = ls->fs;
-+ expdesc args;
-+ int base, nparams;
-+ int line = ls->linenumber;
-+ switch (ls->t.token) {
-+ case '(': { /* funcargs -> `(' [ explist1 ] `)' */
-+ if (line != ls->lastline)
-+ luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
-+ luaX_next(ls);
-+ if (ls->t.token == ')') /* arg list is empty? */
-+ args.k = VVOID;
-+ else {
-+ explist1(ls, &args);
-+ luaK_setmultret(fs, &args);
-+ }
-+ check_match(ls, ')', '(', line);
-+ break;
-+ }
-+ case '{': { /* funcargs -> constructor */
-+ constructor(ls, &args);
-+ break;
-+ }
-+ case TK_STRING: { /* funcargs -> STRING */
-+ codestring(ls, &args, ls->t.seminfo.ts);
-+ luaX_next(ls); /* must use `seminfo' before `next' */
-+ break;
-+ }
-+ default: {
-+ luaX_syntaxerror(ls, "function arguments expected");
-+ return;
-+ }
-+ }
-+ lua_assert(f->k == VNONRELOC);
-+ base = f->u.s.info; /* base register for call */
-+ if (hasmultret(args.k))
-+ nparams = LUA_MULTRET; /* open call */
-+ else {
-+ if (args.k != VVOID)
-+ luaK_exp2nextreg(fs, &args); /* close last argument */
-+ nparams = fs->freereg - (base+1);
-+ }
-+ init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
-+ luaK_fixline(fs, line);
-+ fs->freereg = base+1; /* call remove function and arguments and leaves
-+ (unless changed) one result */
-+}
-+
-+
-+
-+
-+/*
-+** {======================================================================
-+** Expression parsing
-+** =======================================================================
-+*/
-+
-+
-+static void prefixexp (LexState *ls, expdesc *v) {
-+ /* prefixexp -> NAME | '(' expr ')' */
-+ switch (ls->t.token) {
-+ case '(': {
-+ int line = ls->linenumber;
-+ luaX_next(ls);
-+ expr(ls, v);
-+ check_match(ls, ')', '(', line);
-+ luaK_dischargevars(ls->fs, v);
-+ return;
-+ }
-+ case TK_NAME: {
-+ singlevar(ls, v);
-+ return;
-+ }
-+ default: {
-+ luaX_syntaxerror(ls, "unexpected symbol");
-+ return;
-+ }
-+ }
-+}
-+
-+
-+static void primaryexp (LexState *ls, expdesc *v) {
-+ /* primaryexp ->
-+ prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
-+ FuncState *fs = ls->fs;
-+ prefixexp(ls, v);
-+ for (;;) {
-+ switch (ls->t.token) {
-+ case '.': { /* field */
-+ field(ls, v);
-+ break;
-+ }
-+ case '[': { /* `[' exp1 `]' */
-+ expdesc key;
-+ luaK_exp2anyreg(fs, v);
-+ yindex(ls, &key);
-+ luaK_indexed(fs, v, &key);
-+ break;
-+ }
-+ case ':': { /* `:' NAME funcargs */
-+ expdesc key;
-+ luaX_next(ls);
-+ checkname(ls, &key);
-+ luaK_self(fs, v, &key);
-+ funcargs(ls, v);
-+ break;
-+ }
-+ case '(': case TK_STRING: case '{': { /* funcargs */
-+ luaK_exp2nextreg(fs, v);
-+ funcargs(ls, v);
-+ break;
-+ }
-+ default: return;
-+ }
-+ }
-+}
-+
-+
-+static void simpleexp (LexState *ls, expdesc *v) {
-+ /* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
-+ constructor | FUNCTION body | primaryexp */
-+ switch (ls->t.token) {
-+ case TK_NUMBER: {
-+ init_exp(v, VKNUM, 0);
-+ v->u.nval = ls->t.seminfo.r;
-+ break;
-+ }
-+ case TK_STRING: {
-+ codestring(ls, v, ls->t.seminfo.ts);
-+ break;
-+ }
-+ case TK_NIL: {
-+ init_exp(v, VNIL, 0);
-+ break;
-+ }
-+ case TK_TRUE: {
-+ init_exp(v, VTRUE, 0);
-+ break;
-+ }
-+ case TK_FALSE: {
-+ init_exp(v, VFALSE, 0);
-+ break;
-+ }
-+ case TK_DOTS: { /* vararg */
-+ FuncState *fs = ls->fs;
-+ check_condition(ls, fs->f->is_vararg,
-+ "cannot use " LUA_QL("...") " outside a vararg function");
-+ fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
-+ init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
-+ break;
-+ }
-+ case '{': { /* constructor */
-+ constructor(ls, v);
-+ return;
-+ }
-+ case TK_FUNCTION: {
-+ luaX_next(ls);
-+ body(ls, v, 0, ls->linenumber);
-+ return;
-+ }
-+ default: {
-+ primaryexp(ls, v);
-+ return;
-+ }
-+ }
-+ luaX_next(ls);
-+}
-+
-+
-+static UnOpr getunopr (int op) {
-+ switch (op) {
-+ case TK_NOT: return OPR_NOT;
-+ case '-': return OPR_MINUS;
-+ case '#': return OPR_LEN;
-+ default: return OPR_NOUNOPR;
-+ }
-+}
-+
-+
-+static BinOpr getbinopr (int op) {
-+ switch (op) {
-+ case '+': return OPR_ADD;
-+ case '-': return OPR_SUB;
-+ case '*': return OPR_MUL;
-+ case '/': return OPR_DIV;
-+ case '%': return OPR_MOD;
-+ case '^': return OPR_POW;
-+ case TK_CONCAT: return OPR_CONCAT;
-+ case TK_NE: return OPR_NE;
-+ case TK_EQ: return OPR_EQ;
-+ case '<': return OPR_LT;
-+ case TK_LE: return OPR_LE;
-+ case '>': return OPR_GT;
-+ case TK_GE: return OPR_GE;
-+ case TK_AND: return OPR_AND;
-+ case TK_OR: return OPR_OR;
-+ default: return OPR_NOBINOPR;
-+ }
-+}
-+
-+
-+static const struct {
-+ lu_byte left; /* left priority for each binary operator */
-+ lu_byte right; /* right priority */
-+} priority[] = { /* ORDER OPR */
-+ {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
-+ {10, 9}, {5, 4}, /* power and concat (right associative) */
-+ {3, 3}, {3, 3}, /* equality and inequality */
-+ {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
-+ {2, 2}, {1, 1} /* logical (and/or) */
-+};
-+
-+#define UNARY_PRIORITY 8 /* priority for unary operators */
-+
-+
-+/*
-+** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
-+** where `binop' is any binary operator with a priority higher than `limit'
-+*/
-+static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
-+ BinOpr op;
-+ UnOpr uop;
-+ enterlevel(ls);
-+ uop = getunopr(ls->t.token);
-+ if (uop != OPR_NOUNOPR) {
-+ luaX_next(ls);
-+ subexpr(ls, v, UNARY_PRIORITY);
-+ luaK_prefix(ls->fs, uop, v);
-+ }
-+ else simpleexp(ls, v);
-+ /* expand while operators have priorities higher than `limit' */
-+ op = getbinopr(ls->t.token);
-+ while (op != OPR_NOBINOPR && priority[op].left > limit) {
-+ expdesc v2;
-+ BinOpr nextop;
-+ luaX_next(ls);
-+ luaK_infix(ls->fs, op, v);
-+ /* read sub-expression with higher priority */
-+ nextop = subexpr(ls, &v2, priority[op].right);
-+ luaK_posfix(ls->fs, op, v, &v2);
-+ op = nextop;
-+ }
-+ leavelevel(ls);
-+ return op; /* return first untreated operator */
-+}
-+
-+
-+static void expr (LexState *ls, expdesc *v) {
-+ subexpr(ls, v, 0);
-+}
-+
-+/* }==================================================================== */
-+
-+
-+
-+/*
-+** {======================================================================
-+** Rules for Statements
-+** =======================================================================
-+*/
-+
-+
-+static int block_follow (int token) {
-+ switch (token) {
-+ case TK_ELSE: case TK_ELSEIF: case TK_END:
-+ case TK_UNTIL: case TK_EOS:
-+ return 1;
-+ default: return 0;
-+ }
-+}
-+
-+
-+static void block (LexState *ls) {
-+ /* block -> chunk */
-+ FuncState *fs = ls->fs;
-+ BlockCnt bl;
-+ enterblock(fs, &bl, 0);
-+ chunk(ls);
-+ lua_assert(bl.breaklist == NO_JUMP);
-+ leaveblock(fs);
-+}
-+
-+
-+/*
-+** structure to chain all variables in the left-hand side of an
-+** assignment
-+*/
-+struct LHS_assign {
-+ struct LHS_assign *prev;
-+ expdesc v; /* variable (global, local, upvalue, or indexed) */
-+};
-+
-+
-+/*
-+** check whether, in an assignment to a local variable, the local variable
-+** is needed in a previous assignment (to a table). If so, save original
-+** local value in a safe place and use this safe copy in the previous
-+** assignment.
-+*/
-+static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
-+ FuncState *fs = ls->fs;
-+ int extra = fs->freereg; /* eventual position to save local variable */
-+ int conflict = 0;
-+ for (; lh; lh = lh->prev) {
-+ if (lh->v.k == VINDEXED) {
-+ if (lh->v.u.s.info == v->u.s.info) { /* conflict? */
-+ conflict = 1;
-+ lh->v.u.s.info = extra; /* previous assignment will use safe copy */
-+ }
-+ if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */
-+ conflict = 1;
-+ lh->v.u.s.aux = extra; /* previous assignment will use safe copy */
-+ }
-+ }
-+ }
-+ if (conflict) {
-+ luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */
-+ luaK_reserveregs(fs, 1);
-+ }
-+}
-+
-+
-+static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
-+ expdesc e;
-+ check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
-+ "syntax error");
-+ if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
-+ struct LHS_assign nv;
-+ nv.prev = lh;
-+ primaryexp(ls, &nv.v);
-+ if (nv.v.k == VLOCAL)
-+ check_conflict(ls, lh, &nv.v);
-+ luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
-+ "variables in assignment");
-+ assignment(ls, &nv, nvars+1);
-+ }
-+ else { /* assignment -> `=' explist1 */
-+ int nexps;
-+ checknext(ls, '=');
-+ nexps = explist1(ls, &e);
-+ if (nexps != nvars) {
-+ adjust_assign(ls, nvars, nexps, &e);
-+ if (nexps > nvars)
-+ ls->fs->freereg -= nexps - nvars; /* remove extra values */
-+ }
-+ else {
-+ luaK_setoneret(ls->fs, &e); /* close last expression */
-+ luaK_storevar(ls->fs, &lh->v, &e);
-+ return; /* avoid default */
-+ }
-+ }
-+ init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */
-+ luaK_storevar(ls->fs, &lh->v, &e);
-+}
-+
-+
-+static int cond (LexState *ls) {
-+ /* cond -> exp */
-+ expdesc v;
-+ expr(ls, &v); /* read condition */
-+ if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */
-+ luaK_goiftrue(ls->fs, &v);
-+ return v.f;
-+}
-+
-+
-+static void breakstat (LexState *ls) {
-+ FuncState *fs = ls->fs;
-+ BlockCnt *bl = fs->bl;
-+ int upval = 0;
-+ while (bl && !bl->isbreakable) {
-+ upval |= bl->upval;
-+ bl = bl->previous;
-+ }
-+ if (!bl)
-+ luaX_syntaxerror(ls, "no loop to break");
-+ if (upval)
-+ luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
-+ luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
-+}
-+
-+
-+static void whilestat (LexState *ls, int line) {
-+ /* whilestat -> WHILE cond DO block END */
-+ FuncState *fs = ls->fs;
-+ int whileinit;
-+ int condexit;
-+ BlockCnt bl;
-+ luaX_next(ls); /* skip WHILE */
-+ whileinit = luaK_getlabel(fs);
-+ condexit = cond(ls);
-+ enterblock(fs, &bl, 1);
-+ checknext(ls, TK_DO);
-+ block(ls);
-+ luaK_patchlist(fs, luaK_jump(fs), whileinit);
-+ check_match(ls, TK_END, TK_WHILE, line);
-+ leaveblock(fs);
-+ luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
-+}
-+
-+
-+static void repeatstat (LexState *ls, int line) {
-+ /* repeatstat -> REPEAT block UNTIL cond */
-+ int condexit;
-+ FuncState *fs = ls->fs;
-+ int repeat_init = luaK_getlabel(fs);
-+ BlockCnt bl1, bl2;
-+ enterblock(fs, &bl1, 1); /* loop block */
-+ enterblock(fs, &bl2, 0); /* scope block */
-+ luaX_next(ls); /* skip REPEAT */
-+ chunk(ls);
-+ check_match(ls, TK_UNTIL, TK_REPEAT, line);
-+ condexit = cond(ls); /* read condition (inside scope block) */
-+ if (!bl2.upval) { /* no upvalues? */
-+ leaveblock(fs); /* finish scope */
-+ luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */
-+ }
-+ else { /* complete semantics when there are upvalues */
-+ breakstat(ls); /* if condition then break */
-+ luaK_patchtohere(ls->fs, condexit); /* else... */
-+ leaveblock(fs); /* finish scope... */
-+ luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
-+ }
-+ leaveblock(fs); /* finish loop */
-+}
-+
-+
-+static int exp1 (LexState *ls) {
-+ expdesc e;
-+ int k;
-+ expr(ls, &e);
-+ k = e.k;
-+ luaK_exp2nextreg(ls->fs, &e);
-+ return k;
-+}
-+
-+
-+static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
-+ /* forbody -> DO block */
-+ BlockCnt bl;
-+ FuncState *fs = ls->fs;
-+ int prep, endfor;
-+ adjustlocalvars(ls, 3); /* control variables */
-+ checknext(ls, TK_DO);
-+ prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
-+ enterblock(fs, &bl, 0); /* scope for declared variables */
-+ adjustlocalvars(ls, nvars);
-+ luaK_reserveregs(fs, nvars);
-+ block(ls);
-+ leaveblock(fs); /* end of scope for declared variables */
-+ luaK_patchtohere(fs, prep);
-+ endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
-+ luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
-+ luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
-+ luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
-+}
-+
-+
-+static void fornum (LexState *ls, TString *varname, int line) {
-+ /* fornum -> NAME = exp1,exp1[,exp1] forbody */
-+ FuncState *fs = ls->fs;
-+ int base = fs->freereg;
-+ new_localvarliteral(ls, "(for index)", 0);
-+ new_localvarliteral(ls, "(for limit)", 1);
-+ new_localvarliteral(ls, "(for step)", 2);
-+ new_localvar(ls, varname, 3);
-+ checknext(ls, '=');
-+ exp1(ls); /* initial value */
-+ checknext(ls, ',');
-+ exp1(ls); /* limit */
-+ if (testnext(ls, ','))
-+ exp1(ls); /* optional step */
-+ else { /* default step = 1 */
-+ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
-+ luaK_reserveregs(fs, 1);
-+ }
-+ forbody(ls, base, line, 1, 1);
-+}
-+
-+
-+static void forlist (LexState *ls, TString *indexname) {
-+ /* forlist -> NAME {,NAME} IN explist1 forbody */
-+ FuncState *fs = ls->fs;
-+ expdesc e;
-+ int nvars = 0;
-+ int line;
-+ int base = fs->freereg;
-+ /* create control variables */
-+ new_localvarliteral(ls, "(for generator)", nvars++);
-+ new_localvarliteral(ls, "(for state)", nvars++);
-+ new_localvarliteral(ls, "(for control)", nvars++);
-+ /* create declared variables */
-+ new_localvar(ls, indexname, nvars++);
-+ while (testnext(ls, ','))
-+ new_localvar(ls, str_checkname(ls), nvars++);
-+ checknext(ls, TK_IN);
-+ line = ls->linenumber;
-+ adjust_assign(ls, 3, explist1(ls, &e), &e);
-+ luaK_checkstack(fs, 3); /* extra space to call generator */
-+ forbody(ls, base, line, nvars - 3, 0);
-+}
-+
-+
-+static void forstat (LexState *ls, int line) {
-+ /* forstat -> FOR (fornum | forlist) END */
-+ FuncState *fs = ls->fs;
-+ TString *varname;
-+ BlockCnt bl;
-+ enterblock(fs, &bl, 1); /* scope for loop and control variables */
-+ luaX_next(ls); /* skip `for' */
-+ varname = str_checkname(ls); /* first variable name */
-+ switch (ls->t.token) {
-+ case '=': fornum(ls, varname, line); break;
-+ case ',': case TK_IN: forlist(ls, varname); break;
-+ default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected");
-+ }
-+ check_match(ls, TK_END, TK_FOR, line);
-+ leaveblock(fs); /* loop scope (`break' jumps to this point) */
-+}
-+
-+
-+static int test_then_block (LexState *ls) {
-+ /* test_then_block -> [IF | ELSEIF] cond THEN block */
-+ int condexit;
-+ luaX_next(ls); /* skip IF or ELSEIF */
-+ condexit = cond(ls);
-+ checknext(ls, TK_THEN);
-+ block(ls); /* `then' part */
-+ return condexit;
-+}
-+
-+
-+static void ifstat (LexState *ls, int line) {
-+ /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
-+ FuncState *fs = ls->fs;
-+ int flist;
-+ int escapelist = NO_JUMP;
-+ flist = test_then_block(ls); /* IF cond THEN block */
-+ while (ls->t.token == TK_ELSEIF) {
-+ luaK_concat(fs, &escapelist, luaK_jump(fs));
-+ luaK_patchtohere(fs, flist);
-+ flist = test_then_block(ls); /* ELSEIF cond THEN block */
-+ }
-+ if (ls->t.token == TK_ELSE) {
-+ luaK_concat(fs, &escapelist, luaK_jump(fs));
-+ luaK_patchtohere(fs, flist);
-+ luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
-+ block(ls); /* `else' part */
-+ }
-+ else
-+ luaK_concat(fs, &escapelist, flist);
-+ luaK_patchtohere(fs, escapelist);
-+ check_match(ls, TK_END, TK_IF, line);
-+}
-+
-+
-+static void localfunc (LexState *ls) {
-+ expdesc v, b;
-+ FuncState *fs = ls->fs;
-+ new_localvar(ls, str_checkname(ls), 0);
-+ init_exp(&v, VLOCAL, fs->freereg);
-+ luaK_reserveregs(fs, 1);
-+ adjustlocalvars(ls, 1);
-+ body(ls, &b, 0, ls->linenumber);
-+ luaK_storevar(fs, &v, &b);
-+ /* debug information will only see the variable after this point! */
-+ getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
-+}
-+
-+
-+static void localstat (LexState *ls) {
-+ /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
-+ int nvars = 0;
-+ int nexps;
-+ expdesc e;
-+ do {
-+ new_localvar(ls, str_checkname(ls), nvars++);
-+ } while (testnext(ls, ','));
-+ if (testnext(ls, '='))
-+ nexps = explist1(ls, &e);
-+ else {
-+ e.k = VVOID;
-+ nexps = 0;
-+ }
-+ adjust_assign(ls, nvars, nexps, &e);
-+ adjustlocalvars(ls, nvars);
-+}
-+
-+
-+static int funcname (LexState *ls, expdesc *v) {
-+ /* funcname -> NAME {field} [`:' NAME] */
-+ int needself = 0;
-+ singlevar(ls, v);
-+ while (ls->t.token == '.')
-+ field(ls, v);
-+ if (ls->t.token == ':') {
-+ needself = 1;
-+ field(ls, v);
-+ }
-+ return needself;
-+}
-+
-+
-+static void funcstat (LexState *ls, int line) {
-+ /* funcstat -> FUNCTION funcname body */
-+ int needself;
-+ expdesc v, b;
-+ luaX_next(ls); /* skip FUNCTION */
-+ needself = funcname(ls, &v);
-+ body(ls, &b, needself, line);
-+ luaK_storevar(ls->fs, &v, &b);
-+ luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
-+}
-+
-+
-+static void exprstat (LexState *ls) {
-+ /* stat -> func | assignment */
-+ FuncState *fs = ls->fs;
-+ struct LHS_assign v;
-+ primaryexp(ls, &v.v);
-+ if (v.v.k == VCALL) /* stat -> func */
-+ SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */
-+ else { /* stat -> assignment */
-+ v.prev = NULL;
-+ assignment(ls, &v, 1);
-+ }
-+}
-+
-+
-+static void retstat (LexState *ls) {
-+ /* stat -> RETURN explist */
-+ FuncState *fs = ls->fs;
-+ expdesc e;
-+ int first, nret; /* registers with returned values */
-+ luaX_next(ls); /* skip RETURN */
-+ if (block_follow(ls->t.token) || ls->t.token == ';')
-+ first = nret = 0; /* return no values */
-+ else {
-+ nret = explist1(ls, &e); /* optional return values */
-+ if (hasmultret(e.k)) {
-+ luaK_setmultret(fs, &e);
-+ if (e.k == VCALL && nret == 1) { /* tail call? */
-+ SET_OPCODE(getcode(fs,&e), OP_TAILCALL);
-+ lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar);
-+ }
-+ first = fs->nactvar;
-+ nret = LUA_MULTRET; /* return all values */
-+ }
-+ else {
-+ if (nret == 1) /* only one single value? */
-+ first = luaK_exp2anyreg(fs, &e);
-+ else {
-+ luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */
-+ first = fs->nactvar; /* return all `active' values */
-+ lua_assert(nret == fs->freereg - first);
-+ }
-+ }
-+ }
-+ luaK_ret(fs, first, nret);
-+}
-+
-+
-+static int statement (LexState *ls) {
-+ int line = ls->linenumber; /* may be needed for error messages */
-+ switch (ls->t.token) {
-+ case TK_IF: { /* stat -> ifstat */
-+ ifstat(ls, line);
-+ return 0;
-+ }
-+ case TK_WHILE: { /* stat -> whilestat */
-+ whilestat(ls, line);
-+ return 0;
-+ }
-+ case TK_DO: { /* stat -> DO block END */
-+ luaX_next(ls); /* skip DO */
-+ block(ls);
-+ check_match(ls, TK_END, TK_DO, line);
-+ return 0;
-+ }
-+ case TK_FOR: { /* stat -> forstat */
-+ forstat(ls, line);
-+ return 0;
-+ }
-+ case TK_REPEAT: { /* stat -> repeatstat */
-+ repeatstat(ls, line);
-+ return 0;
-+ }
-+ case TK_FUNCTION: {
-+ funcstat(ls, line); /* stat -> funcstat */
-+ return 0;
-+ }
-+ case TK_LOCAL: { /* stat -> localstat */
-+ luaX_next(ls); /* skip LOCAL */
-+ if (testnext(ls, TK_FUNCTION)) /* local function? */
-+ localfunc(ls);
-+ else
-+ localstat(ls);
-+ return 0;
-+ }
-+ case TK_RETURN: { /* stat -> retstat */
-+ retstat(ls);
-+ return 1; /* must be last statement */
-+ }
-+ case TK_BREAK: { /* stat -> breakstat */
-+ luaX_next(ls); /* skip BREAK */
-+ breakstat(ls);
-+ return 1; /* must be last statement */
-+ }
-+ default: {
-+ exprstat(ls);
-+ return 0; /* to avoid warnings */
-+ }
-+ }
-+}
-+
-+
-+static void chunk (LexState *ls) {
-+ /* chunk -> { stat [`;'] } */
-+ int islast = 0;
-+ enterlevel(ls);
-+ while (!islast && !block_follow(ls->t.token)) {
-+ islast = statement(ls);
-+ testnext(ls, ';');
-+ lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
-+ ls->fs->freereg >= ls->fs->nactvar);
-+ ls->fs->freereg = ls->fs->nactvar; /* free registers */
-+ }
-+ leavelevel(ls);
-+}
-+
-+/* }====================================================================== */
---- /dev/null
-+++ b/extensions/LUA/lua/lparser.h
-@@ -0,0 +1,82 @@
-+/*
-+** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $
-+** Lua Parser
-+** See Copyright Notice in lua.h
-+*/
-+
-+#ifndef lparser_h
-+#define lparser_h
-+
-+#include "llimits.h"
-+#include "lobject.h"
-+#include "lzio.h"
-+
-+
-+/*
-+** Expression descriptor
-+*/
-+
-+typedef enum {
-+ VVOID, /* no value */
-+ VNIL,
-+ VTRUE,
-+ VFALSE,
-+ VK, /* info = index of constant in `k' */
-+ VKNUM, /* nval = numerical value */
-+ VLOCAL, /* info = local register */
-+ VUPVAL, /* info = index of upvalue in `upvalues' */
-+ VGLOBAL, /* info = index of table; aux = index of global name in `k' */
-+ VINDEXED, /* info = table register; aux = index register (or `k') */
-+ VJMP, /* info = instruction pc */
-+ VRELOCABLE, /* info = instruction pc */
-+ VNONRELOC, /* info = result register */
-+ VCALL, /* info = instruction pc */
-+ VVARARG /* info = instruction pc */
-+} expkind;
-+
-+typedef struct expdesc {
-+ expkind k;
-+ union {
-+ struct { int info, aux; } s;
-+ lua_Number nval;
-+ } u;
-+ int t; /* patch list of `exit when true' */
-+ int f; /* patch list of `exit when false' */
-+} expdesc;
-+
-+
-+typedef struct upvaldesc {
-+ lu_byte k;
-+ lu_byte info;
-+} upvaldesc;
-+
-+
-+struct BlockCnt; /* defined in lparser.c */
-+
-+
-+/* state needed to generate code for a given function */
-+typedef struct FuncState {
-+ Proto *f; /* current function header */
-+ Table *h; /* table to find (and reuse) elements in `k' */
-+ struct FuncState *prev; /* enclosing function */
-+ struct LexState *ls; /* lexical state */
-+ struct lua_State *L; /* copy of the Lua state */
-+ struct BlockCnt *bl; /* chain of current blocks */
-+ int pc; /* next position to code (equivalent to `ncode') */
-+ int lasttarget; /* `pc' of last `jump target' */
-+ int jpc; /* list of pending jumps to `pc' */
-+ int freereg; /* first free register */
-+ int nk; /* number of elements in `k' */
-+ int np; /* number of elements in `p' */
-+ short nlocvars; /* number of elements in `locvars' */
-+ lu_byte nactvar; /* number of active local variables */
-+ upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
-+ unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
-+} FuncState;
-+
-+
-+LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
-+ const char *name);
-+
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/lua/lstate.c
-@@ -0,0 +1,214 @@
-+/*
-+** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $
-+** Global State
-+** See Copyright Notice in lua.h
-+*/
-+
-+
-+#include
-+
-+#define lstate_c
-+#define LUA_CORE
-+
-+#include "lua.h"
-+
-+#include "ldebug.h"
-+#include "ldo.h"
-+#include "lfunc.h"
-+#include "lgc.h"
-+#include "llex.h"
-+#include "lmem.h"
-+#include "lstate.h"
-+#include "lstring.h"
-+#include "ltable.h"
-+#include "ltm.h"
-+
-+
-+#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
-+#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
-+#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))
-+
-+
-+/*
-+** Main thread combines a thread state and the global state
-+*/
-+typedef struct LG {
-+ lua_State l;
-+ global_State g;
-+} LG;
-+
-+
-+
-+static void stack_init (lua_State *L1, lua_State *L) {
-+ /* initialize CallInfo array */
-+ L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
-+ L1->ci = L1->base_ci;
-+ L1->size_ci = BASIC_CI_SIZE;
-+ L1->end_ci = L1->base_ci + L1->size_ci - 1;
-+ /* initialize stack array */
-+ L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
-+ L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
-+ L1->top = L1->stack;
-+ L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
-+ /* initialize first ci */
-+ L1->ci->func = L1->top;
-+ setnilvalue(L1->top++); /* `function' entry for this `ci' */
-+ L1->base = L1->ci->base = L1->top;
-+ L1->ci->top = L1->top + LUA_MINSTACK;
-+}
-+
-+
-+static void freestack (lua_State *L, lua_State *L1) {
-+ luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
-+ luaM_freearray(L, L1->stack, L1->stacksize, TValue);
-+}
-+
-+
-+/*
-+** open parts that may cause memory-allocation errors
-+*/
-+static void f_luaopen (lua_State *L, void *ud) {
-+ global_State *g = G(L);
-+ UNUSED(ud);
-+ stack_init(L, L); /* init stack */
-+ sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
-+ sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
-+ luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
-+ luaT_init(L);
-+ luaX_init(L);
-+ luaS_fix(luaS_newliteral(L, MEMERRMSG));
-+ g->GCthreshold = 4*g->totalbytes;
-+}
-+
-+
-+static void preinit_state (lua_State *L, global_State *g) {
-+ G(L) = g;
-+ L->stack = NULL;
-+ L->stacksize = 0;
-+ L->errorJmp = NULL;
-+ L->hook = NULL;
-+ L->hookmask = 0;
-+ L->basehookcount = 0;
-+ L->allowhook = 1;
-+ resethookcount(L);
-+ L->openupval = NULL;
-+ L->size_ci = 0;
-+ L->nCcalls = L->baseCcalls = 0;
-+ L->status = 0;
-+ L->base_ci = L->ci = NULL;
-+ L->savedpc = NULL;
-+ L->errfunc = 0;
-+ setnilvalue(gt(L));
-+}
-+
-+
-+static void close_state (lua_State *L) {
-+ global_State *g = G(L);
-+ luaF_close(L, L->stack); /* close all upvalues for this thread */
-+ luaC_freeall(L); /* collect all objects */
-+ lua_assert(g->rootgc == obj2gco(L));
-+ lua_assert(g->strt.nuse == 0);
-+ luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
-+ luaZ_freebuffer(L, &g->buff);
-+ freestack(L, L);
-+ lua_assert(g->totalbytes == sizeof(LG));
-+ (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
-+}
-+
-+
-+lua_State *luaE_newthread (lua_State *L) {
-+ lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
-+ luaC_link(L, obj2gco(L1), LUA_TTHREAD);
-+ preinit_state(L1, G(L));
-+ stack_init(L1, L); /* init stack */
-+ setobj2n(L, gt(L1), gt(L)); /* share table of globals */
-+ L1->hookmask = L->hookmask;
-+ L1->basehookcount = L->basehookcount;
-+ L1->hook = L->hook;
-+ resethookcount(L1);
-+ lua_assert(iswhite(obj2gco(L1)));
-+ return L1;
-+}
-+
-+
-+void luaE_freethread (lua_State *L, lua_State *L1) {
-+ luaF_close(L1, L1->stack); /* close all upvalues for this thread */
-+ lua_assert(L1->openupval == NULL);
-+ luai_userstatefree(L1);
-+ freestack(L, L1);
-+ luaM_freemem(L, fromstate(L1), state_size(lua_State));
-+}
-+
-+
-+LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
-+ int i;
-+ lua_State *L;
-+ global_State *g;
-+ void *l = (*f)(ud, NULL, 0, state_size(LG));
-+ if (l == NULL) return NULL;
-+ L = tostate(l);
-+ g = &((LG *)L)->g;
-+ L->next = NULL;
-+ L->tt = LUA_TTHREAD;
-+ g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
-+ L->marked = luaC_white(g);
-+ set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
-+ preinit_state(L, g);
-+ g->frealloc = f;
-+ g->ud = ud;
-+ g->mainthread = L;
-+ g->uvhead.u.l.prev = &g->uvhead;
-+ g->uvhead.u.l.next = &g->uvhead;
-+ g->GCthreshold = 0; /* mark it as unfinished state */
-+ g->strt.size = 0;
-+ g->strt.nuse = 0;
-+ g->strt.hash = NULL;
-+ setnilvalue(registry(L));
-+ luaZ_initbuffer(L, &g->buff);
-+ g->panic = NULL;
-+ g->gcstate = GCSpause;
-+ g->rootgc = obj2gco(L);
-+ g->sweepstrgc = 0;
-+ g->sweepgc = &g->rootgc;
-+ g->gray = NULL;
-+ g->grayagain = NULL;
-+ g->weak = NULL;
-+ g->tmudata = NULL;
-+ g->totalbytes = sizeof(LG);
-+ g->gcpause = LUAI_GCPAUSE;
-+ g->gcstepmul = LUAI_GCMUL;
-+ g->gcdept = 0;
-+ for (i=0; imt[i] = NULL;
-+ if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
-+ /* memory allocation error: free partial state */
-+ close_state(L);
-+ L = NULL;
-+ }
-+ else
-+ luai_userstateopen(L);
-+ return L;
-+}
-+
-+
-+static void callallgcTM (lua_State *L, void *ud) {
-+ UNUSED(ud);
-+ luaC_callGCTM(L); /* call GC metamethods for all udata */
-+}
-+
-+
-+LUA_API void lua_close (lua_State *L) {
-+ L = G(L)->mainthread; /* only the main thread can be closed */
-+ lua_lock(L);
-+ luaF_close(L, L->stack); /* close all upvalues for this thread */
-+ luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
-+ L->errfunc = 0; /* no error function during GC metamethods */
-+ do { /* repeat until no more errors */
-+ L->ci = L->base_ci;
-+ L->base = L->top = L->ci->base;
-+ L->nCcalls = L->baseCcalls = 0;
-+ } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
-+ lua_assert(G(L)->tmudata == NULL);
-+ luai_userstateclose(L);
-+ close_state(L);
-+}
-+
---- /dev/null
-+++ b/extensions/LUA/lua/lstate.h
-@@ -0,0 +1,169 @@
-+/*
-+** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $
-+** Global State
-+** See Copyright Notice in lua.h
-+*/
-+
-+#ifndef lstate_h
-+#define lstate_h
-+
-+#include "lua.h"
-+
-+#include "lobject.h"
-+#include "ltm.h"
-+#include "lzio.h"
-+
-+
-+
-+struct lua_longjmp; /* defined in ldo.c */
-+
-+
-+/* table of globals */
-+#define gt(L) (&L->l_gt)
-+
-+/* registry */
-+#define registry(L) (&G(L)->l_registry)
-+
-+
-+/* extra stack space to handle TM calls and some other extras */
-+#define EXTRA_STACK 5
-+
-+
-+#define BASIC_CI_SIZE 8
-+
-+#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
-+
-+
-+
-+typedef struct stringtable {
-+ GCObject **hash;
-+ lu_int32 nuse; /* number of elements */
-+ int size;
-+} stringtable;
-+
-+
-+/*
-+** informations about a call
-+*/
-+typedef struct CallInfo {
-+ StkId base; /* base for this function */
-+ StkId func; /* function index in the stack */
-+ StkId top; /* top for this function */
-+ const Instruction *savedpc;
-+ int nresults; /* expected number of results from this function */
-+ int tailcalls; /* number of tail calls lost under this entry */
-+} CallInfo;
-+
-+
-+
-+#define curr_func(L) (clvalue(L->ci->func))
-+#define ci_func(ci) (clvalue((ci)->func))
-+#define f_isLua(ci) (!ci_func(ci)->c.isC)
-+#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
-+
-+
-+/*
-+** `global state', shared by all threads of this state
-+*/
-+typedef struct global_State {
-+ stringtable strt; /* hash table for strings */
-+ lua_Alloc frealloc; /* function to reallocate memory */
-+ void *ud; /* auxiliary data to `frealloc' */
-+ lu_byte currentwhite;
-+ lu_byte gcstate; /* state of garbage collector */
-+ int sweepstrgc; /* position of sweep in `strt' */
-+ GCObject *rootgc; /* list of all collectable objects */
-+ GCObject **sweepgc; /* position of sweep in `rootgc' */
-+ GCObject *gray; /* list of gray objects */
-+ GCObject *grayagain; /* list of objects to be traversed atomically */
-+ GCObject *weak; /* list of weak tables (to be cleared) */
-+ GCObject *tmudata; /* last element of list of userdata to be GC */
-+ Mbuffer buff; /* temporary buffer for string concatentation */
-+ lu_mem GCthreshold;
-+ lu_mem totalbytes; /* number of bytes currently allocated */
-+ lu_mem estimate; /* an estimate of number of bytes actually in use */
-+ lu_mem gcdept; /* how much GC is `behind schedule' */
-+ int gcpause; /* size of pause between successive GCs */
-+ int gcstepmul; /* GC `granularity' */
-+ lua_CFunction panic; /* to be called in unprotected errors */
-+ TValue l_registry;
-+ struct lua_State *mainthread;
-+ UpVal uvhead; /* head of double-linked list of all open upvalues */
-+ struct Table *mt[NUM_TAGS]; /* metatables for basic types */
-+ TString *tmname[TM_N]; /* array with tag-method names */
-+} global_State;
-+
-+
-+/*
-+** `per thread' state
-+*/
-+struct lua_State {
-+ CommonHeader;
-+ lu_byte status;
-+ StkId top; /* first free slot in the stack */
-+ StkId base; /* base of current function */
-+ global_State *l_G;
-+ CallInfo *ci; /* call info for current function */
-+ const Instruction *savedpc; /* `savedpc' of current function */
-+ StkId stack_last; /* last free slot in the stack */
-+ StkId stack; /* stack base */
-+ CallInfo *end_ci; /* points after end of ci array*/
-+ CallInfo *base_ci; /* array of CallInfo's */
-+ int stacksize;
-+ int size_ci; /* size of array `base_ci' */
-+ unsigned short nCcalls; /* number of nested C calls */
-+ unsigned short baseCcalls; /* nested C calls when resuming coroutine */
-+ lu_byte hookmask;
-+ lu_byte allowhook;
-+ int basehookcount;
-+ int hookcount;
-+ lua_Hook hook;
-+ TValue l_gt; /* table of globals */
-+ TValue env; /* temporary place for environments */
-+ GCObject *openupval; /* list of open upvalues in this stack */
-+ GCObject *gclist;
-+ struct lua_longjmp *errorJmp; /* current error recover point */
-+ ptrdiff_t errfunc; /* current error handling function (stack index) */
-+};
-+
-+
-+#define G(L) (L->l_G)
-+
-+
-+/*
-+** Union of all collectable objects
-+*/
-+union GCObject {
-+ GCheader gch;
-+ union TString ts;
-+ union Udata u;
-+ union Closure cl;
-+ struct Table h;
-+ struct Proto p;
-+ struct UpVal uv;
-+ struct lua_State th; /* thread */
-+};
-+
-+
-+/* macros to convert a GCObject into a specific value */
-+#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
-+#define gco2ts(o) (&rawgco2ts(o)->tsv)
-+#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
-+#define gco2u(o) (&rawgco2u(o)->uv)
-+#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
-+#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
-+#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
-+#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
-+#define ngcotouv(o) \
-+ check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
-+#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
-+
-+/* macro to convert any Lua object into a GCObject */
-+#define obj2gco(v) (cast(GCObject *, (v)))
-+
-+
-+LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
-+LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
-+
-+#endif
-+
---- /dev/null
-+++ b/extensions/LUA/lua/lstring.c
-@@ -0,0 +1,110 @@
-+/*
-+** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
-+** String table (keeps all strings handled by Lua)
-+** See Copyright Notice in lua.h
-+*/
-+
-+#include
-+
-+#define lstring_c
-+#define LUA_CORE
-+
-+#include "lua.h"
-+
-+#include "lmem.h"
-+#include "lobject.h"
-+#include "lstate.h"
-+#include "lstring.h"
-+
-+
-+
-+void luaS_resize (lua_State *L, int newsize) {
-+ GCObject **newhash;
-+ stringtable *tb;
-+ int i;
-+ if (G(L)->gcstate == GCSsweepstring)
-+ return; /* cannot resize during GC traverse */
-+ newhash = luaM_newvector(L, newsize, GCObject *);
-+ tb = &G(L)->strt;
-+ for (i=0; isize; i++) {
-+ GCObject *p = tb->hash[i];
-+ while (p) { /* for each node in the list */
-+ GCObject *next = p->gch.next; /* save next */
-+ unsigned int h = gco2ts(p)->hash;
-+ int h1 = lmod(h, newsize); /* new position */
-+ lua_assert(cast_int(h%newsize) == lmod(h, newsize));
-+ p->gch.next = newhash[h1]; /* chain it */
-+ newhash[h1] = p;
-+ p = next;
-+ }
-+ }
-+ luaM_freearray(L, tb->hash, tb->size, TString *);
-+ tb->size = newsize;
-+ tb->hash = newhash;
-+}
-+
-+
-+static TString *newlstr (lua_State *L, const char *str, size_t l,
-+ unsigned int h) {
-+ TString *ts;
-+ stringtable *tb;
-+ if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
-+ luaM_toobig(L);
-+ ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
-+ ts->tsv.len = l;
-+ ts->tsv.hash = h;
-+ ts->tsv.marked = luaC_white(G(L));
-+ ts->tsv.tt = LUA_TSTRING;
-+ ts->tsv.reserved = 0;
-+ memcpy(ts+1, str, l*sizeof(char));
-+ ((char *)(ts+1))[l] = '\0'; /* ending 0 */
-+ tb = &G(L)->strt;
-+ h = lmod(h, tb->size);
-+ ts->tsv.next = tb->hash[h]; /* chain new entry */
-+ tb->hash[h] = obj2gco(ts);
-+ tb->nuse++;
-+ if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
-+ luaS_resize(L, tb->size*2); /* too crowded */
-+ return ts;
-+}
-+
-+
-+TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
-+ GCObject *o;
-+ unsigned int h = cast(unsigned int, l); /* seed */
-+ size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */
-+ size_t l1;
-+ for (l1=l; l1>=step; l1-=step) /* compute hash */
-+ h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
-+ for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
-+ o != NULL;
-+ o = o->gch.next) {
-+ TString *ts = rawgco2ts(o);
-+ if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
-+ /* string may be dead */
-+ if (isdead(G(L), o)) changewhite(o);
-+ return ts;
-+ }
-+ }
-+ return newlstr(L, str, l, h); /* not found */
-+}
-+
-+
-+Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
-+ Udata *u;
-+ if (s > MAX_SIZET - sizeof(Udata))
-+ luaM_toobig(L);
-+ u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
-+ u->uv.marked = luaC_white(G(L)); /* is not finalized */
-+ u->uv.tt = LUA_TUSERDATA;
-+ u->uv.len = s;
-+ u->uv.metatable = NULL;
-+ u->uv.env = e;
-+ /* chain it on udata list (after main thread) */
-+ u->uv.next = G(L)->mainthread->next;
-+ G(L)->mainthread->next = obj2gco(u);
-+ return u;
-+}
-+
---- /dev/null
-+++ b/extensions/LUA/lua/lstring.h
-@@ -0,0 +1,31 @@
-+/*
-+** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $
-+** String table (keep all strings handled by Lua)
-+** See Copyright Notice in lua.h
-+*/
-+
-+#ifndef lstring_h
-+#define lstring_h
-+
-+
-+#include "lgc.h"
-+#include "lobject.h"
-+#include "lstate.h"
-+
-+
-+#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char))
-+
-+#define sizeudata(u) (sizeof(union Udata)+(u)->len)
-+
-+#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
-+#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
-+ (sizeof(s)/sizeof(char))-1))
-+
-+#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
-+
-+LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
-+LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
-+LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
-+
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/lua/lstrlib.c
-@@ -0,0 +1,883 @@
-+/*
-+** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $
-+** Standard library for string operations and pattern-matching
-+** See Copyright Notice in lua.h
-+*/
-+
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#define lstrlib_c
-+#define LUA_LIB
-+
-+#include "lua.h"
-+
-+#include "lauxlib.h"
-+#include "lualib.h"
-+
-+
-+/* macro to `unsign' a character */
-+#define uchar(c) ((unsigned char)(c))
-+
-+
-+
-+static int str_len (lua_State *L) {
-+ size_t l;
-+ luaL_checklstring(L, 1, &l);
-+ lua_pushinteger(L, l);
-+ return 1;
-+}
-+
-+
-+static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) {
-+ /* relative string position: negative means back from end */
-+ if (pos < 0) pos += (ptrdiff_t)len + 1;
-+ return (pos >= 0) ? pos : 0;
-+}
-+
-+
-+static int str_sub (lua_State *L) {
-+ size_t l;
-+ const char *s = luaL_checklstring(L, 1, &l);
-+ ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
-+ ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
-+ if (start < 1) start = 1;
-+ if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
-+ if (start <= end)
-+ lua_pushlstring(L, s+start-1, end-start+1);
-+ else lua_pushliteral(L, "");
-+ return 1;
-+}
-+
-+
-+static int str_reverse (lua_State *L) {
-+ size_t l;
-+ const char *s = luaL_checklstring(L, 1, &l);
-+ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
-+ if(!b) luaL_error(L, "str_reverse: cannot allocate memory");
-+ luaL_buffinit(L, b);
-+ while (l--) luaL_addchar(b, s[l]);
-+ luaL_pushresult(b);
-+ kfree(b);
-+ return 1;
-+}
-+
-+
-+static int str_lower (lua_State *L) {
-+ size_t l;
-+ size_t i;
-+ const char *s = luaL_checklstring(L, 1, &l);
-+ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
-+ if(!b) luaL_error(L, "str_lower: cannot allocate memory");
-+ luaL_buffinit(L, b);
-+ for (i=0; i 0)
-+ luaL_addlstring(b, s, l);
-+ luaL_pushresult(b);
-+ kfree(b);
-+ return 1;
-+}
-+
-+
-+static int str_byte (lua_State *L) {
-+ size_t l;
-+ const char *s = luaL_checklstring(L, 1, &l);
-+ ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
-+ ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
-+ int n, i;
-+ if (posi <= 0) posi = 1;
-+ if ((size_t)pose > l) pose = l;
-+ if (posi > pose) return 0; /* empty interval; return no values */
-+ n = (int)(pose - posi + 1);
-+ if (posi + n <= pose) /* overflow? */
-+ luaL_error(L, "string slice too long");
-+ luaL_checkstack(L, n, "string slice too long");
-+ for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED)
-+ return luaL_error(ms->L, "invalid capture index");
-+ return l;
-+}
-+
-+
-+static int capture_to_close (MatchState *ms) {
-+ int level = ms->level;
-+ for (level--; level>=0; level--)
-+ if (ms->capture[level].len == CAP_UNFINISHED) return level;
-+ return luaL_error(ms->L, "invalid pattern capture");
-+}
-+
-+
-+static const char *classend (MatchState *ms, const char *p) {
-+ switch (*p++) {
-+ case L_ESC: {
-+ if (*p == '\0')
-+ luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
-+ return p+1;
-+ }
-+ case '[': {
-+ if (*p == '^') p++;
-+ do { /* look for a `]' */
-+ if (*p == '\0')
-+ luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
-+ if (*(p++) == L_ESC && *p != '\0')
-+ p++; /* skip escapes (e.g. `%]') */
-+ } while (*p != ']');
-+ return p+1;
-+ }
-+ default: {
-+ return p;
-+ }
-+ }
-+}
-+
-+
-+static int match_class (int c, int cl) {
-+ int res;
-+ switch (tolower(cl)) {
-+ case 'a' : res = isalpha(c); break;
-+ case 'c' : res = iscntrl(c); break;
-+ case 'd' : res = isdigit(c); break;
-+ case 'l' : res = islower(c); break;
-+ case 'p' : res = ispunct(c); break;
-+ case 's' : res = isspace(c); break;
-+ case 'u' : res = isupper(c); break;
-+ case 'w' : res = isalnum(c); break;
-+ case 'x' : res = isxdigit(c); break;
-+ case 'z' : res = (c == 0); break;
-+ default: return (cl == c);
-+ }
-+ return (islower(cl) ? res : !res);
-+}
-+
-+
-+static int matchbracketclass (int c, const char *p, const char *ec) {
-+ int sig = 1;
-+ if (*(p+1) == '^') {
-+ sig = 0;
-+ p++; /* skip the `^' */
-+ }
-+ while (++p < ec) {
-+ if (*p == L_ESC) {
-+ p++;
-+ if (match_class(c, uchar(*p)))
-+ return sig;
-+ }
-+ else if ((*(p+1) == '-') && (p+2 < ec)) {
-+ p+=2;
-+ if (uchar(*(p-2)) <= c && c <= uchar(*p))
-+ return sig;
-+ }
-+ else if (uchar(*p) == c) return sig;
-+ }
-+ return !sig;
-+}
-+
-+
-+static int singlematch (int c, const char *p, const char *ep) {
-+ switch (*p) {
-+ case '.': return 1; /* matches any char */
-+ case L_ESC: return match_class(c, uchar(*(p+1)));
-+ case '[': return matchbracketclass(c, p, ep-1);
-+ default: return (uchar(*p) == c);
-+ }
-+}
-+
-+
-+static const char *match (MatchState *ms, const char *s, const char *p);
-+
-+
-+static const char *matchbalance (MatchState *ms, const char *s,
-+ const char *p) {
-+ if (*p == 0 || *(p+1) == 0)
-+ luaL_error(ms->L, "unbalanced pattern");
-+ if (*s != *p) return NULL;
-+ else {
-+ int b = *p;
-+ int e = *(p+1);
-+ int cont = 1;
-+ while (++s < ms->src_end) {
-+ if (*s == e) {
-+ if (--cont == 0) return s+1;
-+ }
-+ else if (*s == b) cont++;
-+ }
-+ }
-+ return NULL; /* string ends out of balance */
-+}
-+
-+
-+static const char *max_expand (MatchState *ms, const char *s,
-+ const char *p, const char *ep) {
-+ ptrdiff_t i = 0; /* counts maximum expand for item */
-+ while ((s+i)src_end && singlematch(uchar(*(s+i)), p, ep))
-+ i++;
-+ /* keeps trying to match with the maximum repetitions */
-+ while (i>=0) {
-+ const char *res = match(ms, (s+i), ep+1);
-+ if (res) return res;
-+ i--; /* else didn't match; reduce 1 repetition to try again */
-+ }
-+ return NULL;
-+}
-+
-+
-+static const char *min_expand (MatchState *ms, const char *s,
-+ const char *p, const char *ep) {
-+ for (;;) {
-+ const char *res = match(ms, s, ep+1);
-+ if (res != NULL)
-+ return res;
-+ else if (ssrc_end && singlematch(uchar(*s), p, ep))
-+ s++; /* try with one more repetition */
-+ else return NULL;
-+ }
-+}
-+
-+
-+static const char *start_capture (MatchState *ms, const char *s,
-+ const char *p, int what) {
-+ const char *res;
-+ int level = ms->level;
-+ if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures");
-+ ms->capture[level].init = s;
-+ ms->capture[level].len = what;
-+ ms->level = level+1;
-+ if ((res=match(ms, s, p)) == NULL) /* match failed? */
-+ ms->level--; /* undo capture */
-+ return res;
-+}
-+
-+
-+static const char *end_capture (MatchState *ms, const char *s,
-+ const char *p) {
-+ int l = capture_to_close(ms);
-+ const char *res;
-+ ms->capture[l].len = s - ms->capture[l].init; /* close capture */
-+ if ((res = match(ms, s, p)) == NULL) /* match failed? */
-+ ms->capture[l].len = CAP_UNFINISHED; /* undo capture */
-+ return res;
-+}
-+
-+
-+static const char *match_capture (MatchState *ms, const char *s, int l) {
-+ size_t len;
-+ l = check_capture(ms, l);
-+ len = ms->capture[l].len;
-+ if ((size_t)(ms->src_end-s) >= len &&
-+ memcmp(ms->capture[l].init, s, len) == 0)
-+ return s+len;
-+ else return NULL;
-+}
-+
-+
-+static const char *match (MatchState *ms, const char *s, const char *p) {
-+ init: /* using goto's to optimize tail recursion */
-+ switch (*p) {
-+ case '(': { /* start capture */
-+ if (*(p+1) == ')') /* position capture? */
-+ return start_capture(ms, s, p+2, CAP_POSITION);
-+ else
-+ return start_capture(ms, s, p+1, CAP_UNFINISHED);
-+ }
-+ case ')': { /* end capture */
-+ return end_capture(ms, s, p+1);
-+ }
-+ case L_ESC: {
-+ switch (*(p+1)) {
-+ case 'b': { /* balanced string? */
-+ s = matchbalance(ms, s, p+2);
-+ if (s == NULL) return NULL;
-+ p+=4; goto init; /* else return match(ms, s, p+4); */
-+ }
-+ case 'f': { /* frontier? */
-+ const char *ep; char previous;
-+ p += 2;
-+ if (*p != '[')
-+ luaL_error(ms->L, "missing " LUA_QL("[") " after "
-+ LUA_QL("%%f") " in pattern");
-+ ep = classend(ms, p); /* points to what is next */
-+ previous = (s == ms->src_init) ? '\0' : *(s-1);
-+ if (matchbracketclass(uchar(previous), p, ep-1) ||
-+ !matchbracketclass(uchar(*s), p, ep-1)) return NULL;
-+ p=ep; goto init; /* else return match(ms, s, ep); */
-+ }
-+ default: {
-+ if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
-+ s = match_capture(ms, s, uchar(*(p+1)));
-+ if (s == NULL) return NULL;
-+ p+=2; goto init; /* else return match(ms, s, p+2) */
-+ }
-+ goto dflt; /* case default */
-+ }
-+ }
-+ }
-+ case '\0': { /* end of pattern */
-+ return s; /* match succeeded */
-+ }
-+ case '$': {
-+ if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
-+ return (s == ms->src_end) ? s : NULL; /* check end of string */
-+ else goto dflt;
-+ }
-+ default: dflt: { /* it is a pattern item */
-+ const char *ep = classend(ms, p); /* points to what is next */
-+ int m = ssrc_end && singlematch(uchar(*s), p, ep);
-+ switch (*ep) {
-+ case '?': { /* optional */
-+ const char *res;
-+ if (m && ((res=match(ms, s+1, ep+1)) != NULL))
-+ return res;
-+ p=ep+1; goto init; /* else return match(ms, s, ep+1); */
-+ }
-+ case '*': { /* 0 or more repetitions */
-+ return max_expand(ms, s, p, ep);
-+ }
-+ case '+': { /* 1 or more repetitions */
-+ return (m ? max_expand(ms, s+1, p, ep) : NULL);
-+ }
-+ case '-': { /* 0 or more repetitions (minimum) */
-+ return min_expand(ms, s, p, ep);
-+ }
-+ default: {
-+ if (!m) return NULL;
-+ s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+
-+
-+static const char *lmemfind (const char *s1, size_t l1,
-+ const char *s2, size_t l2) {
-+ if (l2 == 0) return s1; /* empty strings are everywhere */
-+ else if (l2 > l1) return NULL; /* avoids a negative `l1' */
-+ else {
-+ const char *init; /* to search for a `*s2' inside `s1' */
-+ l2--; /* 1st char will be checked by `memchr' */
-+ l1 = l1-l2; /* `s2' cannot be found after that */
-+ while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
-+ init++; /* 1st char is already checked */
-+ if (memcmp(init, s2+1, l2) == 0)
-+ return init-1;
-+ else { /* correct `l1' and `s1' to try again */
-+ l1 -= init-s1;
-+ s1 = init;
-+ }
-+ }
-+ return NULL; /* not found */
-+ }
-+}
-+
-+
-+static void push_onecapture (MatchState *ms, int i, const char *s,
-+ const char *e) {
-+ if (i >= ms->level) {
-+ if (i == 0) /* ms->level == 0, too */
-+ lua_pushlstring(ms->L, s, e - s); /* add whole match */
-+ else
-+ luaL_error(ms->L, "invalid capture index");
-+ }
-+ else {
-+ ptrdiff_t l = ms->capture[i].len;
-+ if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture");
-+ if (l == CAP_POSITION)
-+ lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1);
-+ else
-+ lua_pushlstring(ms->L, ms->capture[i].init, l);
-+ }
-+}
-+
-+
-+static int push_captures (MatchState *ms, const char *s, const char *e) {
-+ int i;
-+ int nlevels = (ms->level == 0 && s) ? 1 : ms->level;
-+ luaL_checkstack(ms->L, nlevels, "too many captures");
-+ for (i = 0; i < nlevels; i++)
-+ push_onecapture(ms, i, s, e);
-+ return nlevels; /* number of strings pushed */
-+}
-+
-+
-+static int str_find_aux (lua_State *L, int find) {
-+ size_t l1, l2;
-+ const char *s = luaL_checklstring(L, 1, &l1);
-+ const char *p = luaL_checklstring(L, 2, &l2);
-+ ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
-+ if (init < 0) init = 0;
-+ else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
-+ if (find && (lua_toboolean(L, 4) || /* explicit request? */
-+ strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
-+ /* do a plain search */
-+ const char *s2 = lmemfind(s+init, l1-init, p, l2);
-+ if (s2) {
-+ lua_pushinteger(L, s2-s+1);
-+ lua_pushinteger(L, s2-s+l2);
-+ return 2;
-+ }
-+ }
-+ else {
-+ MatchState ms;
-+ int anchor = (*p == '^') ? (p++, 1) : 0;
-+ const char *s1=s+init;
-+ ms.L = L;
-+ ms.src_init = s;
-+ ms.src_end = s+l1;
-+ do {
-+ const char *res;
-+ ms.level = 0;
-+ if ((res=match(&ms, s1, p)) != NULL) {
-+ if (find) {
-+ lua_pushinteger(L, s1-s+1); /* start */
-+ lua_pushinteger(L, res-s); /* end */
-+ return push_captures(&ms, NULL, 0) + 2;
-+ }
-+ else
-+ return push_captures(&ms, s1, res);
-+ }
-+ } while (s1++ < ms.src_end && !anchor);
-+ }
-+ lua_pushnil(L); /* not found */
-+ return 1;
-+}
-+
-+
-+static int str_find (lua_State *L) {
-+ return str_find_aux(L, 1);
-+}
-+
-+
-+static int str_match (lua_State *L) {
-+ return str_find_aux(L, 0);
-+}
-+
-+
-+static int gmatch_aux (lua_State *L) {
-+ MatchState ms;
-+ size_t ls;
-+ const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
-+ const char *p = lua_tostring(L, lua_upvalueindex(2));
-+ const char *src;
-+ ms.L = L;
-+ ms.src_init = s;
-+ ms.src_end = s+ls;
-+ for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
-+ src <= ms.src_end;
-+ src++) {
-+ const char *e;
-+ ms.level = 0;
-+ if ((e = match(&ms, src, p)) != NULL) {
-+ lua_Integer newstart = e-s;
-+ if (e == src) newstart++; /* empty match? go at least one position */
-+ lua_pushinteger(L, newstart);
-+ lua_replace(L, lua_upvalueindex(3));
-+ return push_captures(&ms, src, e);
-+ }
-+ }
-+ return 0; /* not found */
-+}
-+
-+
-+static int gmatch (lua_State *L) {
-+ luaL_checkstring(L, 1);
-+ luaL_checkstring(L, 2);
-+ lua_settop(L, 2);
-+ lua_pushinteger(L, 0);
-+ lua_pushcclosure(L, gmatch_aux, 3);
-+ return 1;
-+}
-+
-+
-+static int gfind_nodef (lua_State *L) {
-+ return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
-+ LUA_QL("string.gmatch"));
-+}
-+
-+
-+static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
-+ const char *e) {
-+ size_t l, i;
-+ const char *news = lua_tolstring(ms->L, 3, &l);
-+ for (i = 0; i < l; i++) {
-+ if (news[i] != L_ESC)
-+ luaL_addchar(b, news[i]);
-+ else {
-+ i++; /* skip ESC */
-+ if (!isdigit(uchar(news[i])))
-+ luaL_addchar(b, news[i]);
-+ else if (news[i] == '0')
-+ luaL_addlstring(b, s, e - s);
-+ else {
-+ push_onecapture(ms, news[i] - '1', s, e);
-+ luaL_addvalue(b); /* add capture to accumulated result */
-+ }
-+ }
-+ }
-+}
-+
-+
-+static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
-+ const char *e) {
-+ lua_State *L = ms->L;
-+ switch (lua_type(L, 3)) {
-+ case LUA_TNUMBER:
-+ case LUA_TSTRING: {
-+ add_s(ms, b, s, e);
-+ return;
-+ }
-+ case LUA_TFUNCTION: {
-+ int n;
-+ lua_pushvalue(L, 3);
-+ n = push_captures(ms, s, e);
-+ lua_call(L, n, 1);
-+ break;
-+ }
-+ case LUA_TTABLE: {
-+ push_onecapture(ms, 0, s, e);
-+ lua_gettable(L, 3);
-+ break;
-+ }
-+ }
-+ if (!lua_toboolean(L, -1)) { /* nil or false? */
-+ lua_pop(L, 1);
-+ lua_pushlstring(L, s, e - s); /* keep original text */
-+ }
-+ else if (!lua_isstring(L, -1))
-+ luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
-+ luaL_addvalue(b); /* add result to accumulator */
-+}
-+
-+
-+static int str_gsub (lua_State *L) {
-+ size_t srcl;
-+ const char *src = luaL_checklstring(L, 1, &srcl);
-+ const char *p = luaL_checkstring(L, 2);
-+ int tr = lua_type(L, 3);
-+ int max_s = luaL_optint(L, 4, srcl+1);
-+ int anchor = (*p == '^') ? (p++, 1) : 0;
-+ int n = 0;
-+ MatchState ms;
-+ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
-+ if(!b) luaL_error(L, "str_gsub: cannot allocate memory");
-+ luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
-+ tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
-+ "string/function/table expected");
-+ luaL_buffinit(L, b);
-+ ms.L = L;
-+ ms.src_init = src;
-+ ms.src_end = src+srcl;
-+ while (n < max_s) {
-+ const char *e;
-+ ms.level = 0;
-+ e = match(&ms, src, p);
-+ if (e) {
-+ n++;
-+ add_value(&ms, b, src, e);
-+ }
-+ if (e && e>src) /* non empty match? */
-+ src = e; /* skip it */
-+ else if (src < ms.src_end)
-+ luaL_addchar(b, *src++);
-+ else break;
-+ if (anchor) break;
-+ }
-+ luaL_addlstring(b, src, ms.src_end-src);
-+ luaL_pushresult(b);
-+ lua_pushinteger(L, n); /* number of substitutions */
-+ kfree(b);
-+ return 2;
-+}
-+
-+/* }====================================================== */
-+
-+
-+/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
-+#define MAX_ITEM 512
-+/* valid flags in a format specification */
-+#define FLAGS "-+ #0"
-+/*
-+** maximum size of each format specification (such as '%-099.99d')
-+** (+10 accounts for %99.99x plus margin of error)
-+*/
-+#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
-+
-+
-+static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
-+ size_t l;
-+ const char *s = luaL_checklstring(L, arg, &l);
-+ luaL_addchar(b, '"');
-+ while (l--) {
-+ switch (*s) {
-+ case '"': case '\\': case '\n': {
-+ luaL_addchar(b, '\\');
-+ luaL_addchar(b, *s);
-+ break;
-+ }
-+ case '\r': {
-+ luaL_addlstring(b, "\\r", 2);
-+ break;
-+ }
-+ case '\0': {
-+ luaL_addlstring(b, "\\000", 4);
-+ break;
-+ }
-+ default: {
-+ luaL_addchar(b, *s);
-+ break;
-+ }
-+ }
-+ s++;
-+ }
-+ luaL_addchar(b, '"');
-+}
-+
-+static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
-+ const char *p = strfrmt;
-+ while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
-+ if ((size_t)(p - strfrmt) >= sizeof(FLAGS))
-+ luaL_error(L, "invalid format (repeated flags)");
-+ if (isdigit(uchar(*p))) p++; /* skip width */
-+ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
-+ if (*p == '.') {
-+ p++;
-+ if (isdigit(uchar(*p))) p++; /* skip precision */
-+ if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
-+ }
-+ if (isdigit(uchar(*p)))
-+ luaL_error(L, "invalid format (width or precision too long)");
-+ *(form++) = '%';
-+ strncpy(form, strfrmt, p - strfrmt + 1);
-+ form += p - strfrmt + 1;
-+ *form = '\0';
-+ return p;
-+}
-+
-+
-+static void addintlen (char *form) {
-+ size_t l = strlen(form);
-+ char spec = form[l - 1];
-+ strcpy(form + l - 1, LUA_INTFRMLEN);
-+ form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
-+ form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
-+}
-+
-+
-+static int str_format (lua_State *L) {
-+ int arg = 1;
-+ size_t sfl;
-+ const char *strfrmt = luaL_checklstring(L, arg, &sfl);
-+ const char *strfrmt_end = strfrmt+sfl;
-+ luaL_Buffer *b = (luaL_Buffer *)kmalloc(sizeof(luaL_Buffer) + BUFSIZ, GFP_ATOMIC);
-+ if(!b) luaL_error(L, "str_format: cannot allocate memory");
-+ luaL_buffinit(L, b);
-+ while (strfrmt < strfrmt_end) {
-+ if (*strfrmt != L_ESC)
-+ luaL_addchar(b, *strfrmt++);
-+ else if (*++strfrmt == L_ESC)
-+ luaL_addchar(b, *strfrmt++); /* %% */
-+ else { /* format item */
-+ char form[MAX_FORMAT]; /* to store the format (`%...') */
-+ char buff[MAX_ITEM]; /* to store the formatted item */
-+ arg++;
-+ strfrmt = scanformat(L, strfrmt, form);
-+ switch (*strfrmt++) {
-+ case 'c': {
-+ sprintf(buff, form, (int)luaL_checknumber(L, arg));
-+ break;
-+ }
-+ case 'd': case 'i': {
-+ addintlen(form);
-+ sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
-+ break;
-+ }
-+ case 'o': case 'u': case 'x': case 'X': {
-+ addintlen(form);
-+ sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
-+ break;
-+ }
-+ case 'q': {
-+ addquoted(L, b, arg);
-+ continue; /* skip the 'addsize' at the end */
-+ }
-+ case 's': {
-+ size_t l;
-+ const char *s = luaL_checklstring(L, arg, &l);
-+ if (!strchr(form, '.') && l >= 100) {
-+ /* no precision and string is too long to be formatted;
-+ keep original string */
-+ lua_pushvalue(L, arg);
-+ luaL_addvalue(b);
-+ continue; /* skip the `addsize' at the end */
-+ }
-+ else {
-+ sprintf(buff, form, s);
-+ break;
-+ }
-+ }
-+ default: { /* also treat cases `pnLlh' */
-+ kfree(b);
-+ return luaL_error(L, "invalid option " LUA_QL("%%%c") " to "
-+ LUA_QL("format"), *(strfrmt - 1));
-+ }
-+ }
-+ luaL_addlstring(b, buff, strlen(buff));
-+ }
-+ }
-+ luaL_pushresult(b);
-+ kfree(b);
-+ return 1;
-+}
-+
-+
-+static const luaL_Reg strlib[] = {
-+ {"byte", str_byte},
-+ {"char", str_char},
-+ {"dump", str_dump},
-+ {"find", str_find},
-+ {"format", str_format},
-+ {"gfind", gfind_nodef},
-+ {"gmatch", gmatch},
-+ {"gsub", str_gsub},
-+ {"len", str_len},
-+ {"lower", str_lower},
-+ {"match", str_match},
-+ {"rep", str_rep},
-+ {"reverse", str_reverse},
-+ {"sub", str_sub},
-+ {"upper", str_upper},
-+ {NULL, NULL}
-+};
-+
-+
-+static void createmetatable (lua_State *L) {
-+ lua_createtable(L, 0, 1); /* create metatable for strings */
-+ lua_pushliteral(L, ""); /* dummy string */
-+ lua_pushvalue(L, -2);
-+ lua_setmetatable(L, -2); /* set string metatable */
-+ lua_pop(L, 1); /* pop dummy string */
-+ lua_pushvalue(L, -2); /* string library... */
-+ lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
-+ lua_pop(L, 1); /* pop metatable */
-+}
-+
-+
-+/*
-+** Open string library
-+*/
-+LUALIB_API int luaopen_string (lua_State *L) {
-+ luaL_register(L, LUA_STRLIBNAME, strlib);
-+#if defined(LUA_COMPAT_GFIND)
-+ lua_getfield(L, -1, "gmatch");
-+ lua_setfield(L, -2, "gfind");
-+#endif
-+ createmetatable(L);
-+ return 1;
-+}
---- /dev/null
-+++ b/extensions/LUA/lua/ltable.c
-@@ -0,0 +1,588 @@
-+/*
-+** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $
-+** Lua tables (hash)
-+** See Copyright Notice in lua.h
-+*/
-+
-+
-+/*
-+** Implementation of tables (aka arrays, objects, or hash tables).
-+** Tables keep its elements in two parts: an array part and a hash part.
-+** Non-negative integer keys are all candidates to be kept in the array
-+** part. The actual size of the array is the largest `n' such that at
-+** least half the slots between 0 and n are in use.
-+** Hash uses a mix of chained scatter table with Brent's variation.
-+** A main invariant of these tables is that, if an element is not
-+** in its main position (i.e. the `original' position that its hash gives
-+** to it), then the colliding element is in its own main position.
-+** Hence even when the load factor reaches 100%, performance remains good.
-+*/
-+
-+#include
-+#include
-+
-+#define ltable_c
-+#define LUA_CORE
-+
-+#include "lua.h"
-+
-+#include "ldebug.h"
-+#include "ldo.h"
-+#include "lgc.h"
-+#include "lmem.h"
-+#include "lobject.h"
-+#include "lstate.h"
-+#include "ltable.h"
-+
-+
-+/*
-+** max size of array part is 2^MAXBITS
-+*/
-+#if LUAI_BITSINT > 26
-+#define MAXBITS 26
-+#else
-+#define MAXBITS (LUAI_BITSINT-2)
-+#endif
-+
-+#define MAXASIZE (1 << MAXBITS)
-+
-+
-+#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
-+
-+#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
-+#define hashboolean(t,p) hashpow2(t, p)
-+
-+
-+/*
-+** for some types, it is better to avoid modulus by power of 2, as
-+** they tend to have many 2 factors.
-+*/
-+#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
-+
-+
-+#define hashpointer(t,p) hashmod(t, IntPoint(p))
-+
-+
-+/*
-+** number of ints inside a lua_Number
-+*/
-+#define numints cast_int(sizeof(lua_Number)/sizeof(int))
-+
-+
-+
-+#define dummynode (&dummynode_)
-+
-+static const Node dummynode_ = {
-+ {{NULL}, LUA_TNIL}, /* value */
-+ {{{NULL}, LUA_TNIL, NULL}} /* key */
-+};
-+
-+
-+/*
-+** hash for lua_Numbers
-+*/
-+static Node *hashnum (const Table *t, lua_Number n) {
-+ unsigned int a[numints];
-+ int i;
-+ if (luai_numeq(n, 0)) /* avoid problems with -0 */
-+ return gnode(t, 0);
-+ memcpy(a, &n, sizeof(a));
-+ for (i = 1; i < numints; i++) a[0] += a[i];
-+ return hashmod(t, a[0]);
-+}
-+
-+
-+
-+/*
-+** returns the `main' position of an element in a table (that is, the index
-+** of its hash value)
-+*/
-+static Node *mainposition (const Table *t, const TValue *key) {
-+ switch (ttype(key)) {
-+ case LUA_TNUMBER:
-+ return hashnum(t, nvalue(key));
-+ case LUA_TSTRING:
-+ return hashstr(t, rawtsvalue(key));
-+ case LUA_TBOOLEAN:
-+ return hashboolean(t, bvalue(key));
-+ case LUA_TLIGHTUSERDATA:
-+ return hashpointer(t, pvalue(key));
-+ default:
-+ return hashpointer(t, gcvalue(key));
-+ }
-+}
-+
-+
-+/*
-+** returns the index for `key' if `key' is an appropriate key to live in
-+** the array part of the table, -1 otherwise.
-+*/
-+static int arrayindex (const TValue *key) {
-+ if (ttisnumber(key)) {
-+ lua_Number n = nvalue(key);
-+ int k;
-+ lua_number2int(k, n);
-+ if (luai_numeq(cast_num(k), n))
-+ return k;
-+ }
-+ return -1; /* `key' did not match some condition */
-+}
-+
-+
-+/*
-+** returns the index of a `key' for table traversals. First goes all
-+** elements in the array part, then elements in the hash part. The
-+** beginning of a traversal is signalled by -1.
-+*/
-+static int findindex (lua_State *L, Table *t, StkId key) {
-+ int i;
-+ if (ttisnil(key)) return -1; /* first iteration */
-+ i = arrayindex(key);
-+ if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
-+ return i-1; /* yes; that's the index (corrected to C) */
-+ else {
-+ Node *n = mainposition(t, key);
-+ do { /* check whether `key' is somewhere in the chain */
-+ /* key may be dead already, but it is ok to use it in `next' */
-+ if (luaO_rawequalObj(key2tval(n), key) ||
-+ (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
-+ gcvalue(gkey(n)) == gcvalue(key))) {
-+ i = cast_int(n - gnode(t, 0)); /* key index in hash table */
-+ /* hash elements are numbered after array ones */
-+ return i + t->sizearray;
-+ }
-+ else n = gnext(n);
-+ } while (n);
-+ luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
-+ return 0; /* to avoid warnings */
-+ }
-+}
-+
-+
-+int luaH_next (lua_State *L, Table *t, StkId key) {
-+ int i = findindex(L, t, key); /* find original element */
-+ for (i++; i < t->sizearray; i++) { /* try first array part */
-+ if (!ttisnil(&t->array[i])) { /* a non-nil value? */
-+ setnvalue(key, cast_num(i+1));
-+ setobj2s(L, key+1, &t->array[i]);
-+ return 1;
-+ }
-+ }
-+ for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
-+ if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
-+ setobj2s(L, key, key2tval(gnode(t, i)));
-+ setobj2s(L, key+1, gval(gnode(t, i)));
-+ return 1;
-+ }
-+ }
-+ return 0; /* no more elements */
-+}
-+
-+
-+/*
-+** {=============================================================
-+** Rehash
-+** ==============================================================
-+*/
-+
-+
-+static int computesizes (int nums[], int *narray) {
-+ int i;
-+ int twotoi; /* 2^i */
-+ int a = 0; /* number of elements smaller than 2^i */
-+ int na = 0; /* number of elements to go to array part */
-+ int n = 0; /* optimal size for array part */
-+ for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) {
-+ if (nums[i] > 0) {
-+ a += nums[i];
-+ if (a > twotoi/2) { /* more than half elements present? */
-+ n = twotoi; /* optimal size (till now) */
-+ na = a; /* all elements smaller than n will go to array part */
-+ }
-+ }
-+ if (a == *narray) break; /* all elements already counted */
-+ }
-+ *narray = n;
-+ lua_assert(*narray/2 <= na && na <= *narray);
-+ return na;
-+}
-+
-+
-+static int countint (const TValue *key, int *nums) {
-+ int k = arrayindex(key);
-+ if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
-+ nums[ceillog2(k)]++; /* count as such */
-+ return 1;
-+ }
-+ else
-+ return 0;
-+}
-+
-+
-+static int numusearray (const Table *t, int *nums) {
-+ int lg;
-+ int ttlg; /* 2^lg */
-+ int ause = 0; /* summation of `nums' */
-+ int i = 1; /* count to traverse all array keys */
-+ for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */
-+ int lc = 0; /* counter */
-+ int lim = ttlg;
-+ if (lim > t->sizearray) {
-+ lim = t->sizearray; /* adjust upper limit */
-+ if (i > lim)
-+ break; /* no more elements to count */
-+ }
-+ /* count elements in range (2^(lg-1), 2^lg] */
-+ for (; i <= lim; i++) {
-+ if (!ttisnil(&t->array[i-1]))
-+ lc++;
-+ }
-+ nums[lg] += lc;
-+ ause += lc;
-+ }
-+ return ause;
-+}
-+
-+
-+static int numusehash (const Table *t, int *nums, int *pnasize) {
-+ int totaluse = 0; /* total number of elements */
-+ int ause = 0; /* summation of `nums' */
-+ int i = sizenode(t);
-+ while (i--) {
-+ Node *n = &t->node[i];
-+ if (!ttisnil(gval(n))) {
-+ ause += countint(key2tval(n), nums);
-+ totaluse++;
-+ }
-+ }
-+ *pnasize += ause;
-+ return totaluse;
-+}
-+
-+
-+static void setarrayvector (lua_State *L, Table *t, int size) {
-+ int i;
-+ luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
-+ for (i=t->sizearray; iarray[i]);
-+ t->sizearray = size;
-+}
-+
-+
-+static void setnodevector (lua_State *L, Table *t, int size) {
-+ int lsize;
-+ if (size == 0) { /* no elements to hash part? */
-+ t->node = cast(Node *, dummynode); /* use common `dummynode' */
-+ lsize = 0;
-+ }
-+ else {
-+ int i;
-+ lsize = ceillog2(size);
-+ if (lsize > MAXBITS)
-+ luaG_runerror(L, "table overflow");
-+ size = twoto(lsize);
-+ t->node = luaM_newvector(L, size, Node);
-+ for (i=0; ilsizenode = cast_byte(lsize);
-+ t->lastfree = gnode(t, size); /* all positions are free */
-+}
-+
-+
-+static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
-+ int i;
-+ int oldasize = t->sizearray;
-+ int oldhsize = t->lsizenode;
-+ Node *nold = t->node; /* save old hash ... */
-+ if (nasize > oldasize) /* array part must grow? */
-+ setarrayvector(L, t, nasize);
-+ /* create new hash part with appropriate size */
-+ setnodevector(L, t, nhsize);
-+ if (nasize < oldasize) { /* array part must shrink? */
-+ t->sizearray = nasize;
-+ /* re-insert elements from vanishing slice */
-+ for (i=nasize; iarray[i]))
-+ setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
-+ }
-+ /* shrink array */
-+ luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
-+ }
-+ /* re-insert elements from hash part */
-+ for (i = twoto(oldhsize) - 1; i >= 0; i--) {
-+ Node *old = nold+i;
-+ if (!ttisnil(gval(old)))
-+ setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
-+ }
-+ if (nold != dummynode)
-+ luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
-+}
-+
-+
-+void luaH_resizearray (lua_State *L, Table *t, int nasize) {
-+ int nsize = (t->node == dummynode) ? 0 : sizenode(t);
-+ resize(L, t, nasize, nsize);
-+}
-+
-+
-+static void rehash (lua_State *L, Table *t, const TValue *ek) {
-+ int nasize, na;
-+ int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
-+ int i;
-+ int totaluse;
-+ for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
-+ nasize = numusearray(t, nums); /* count keys in array part */
-+ totaluse = nasize; /* all those keys are integer keys */
-+ totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */
-+ /* count extra key */
-+ nasize += countint(ek, nums);
-+ totaluse++;
-+ /* compute new size for array part */
-+ na = computesizes(nums, &nasize);
-+ /* resize the table to new computed sizes */
-+ resize(L, t, nasize, totaluse - na);
-+}
-+
-+
-+
-+/*
-+** }=============================================================
-+*/
-+
-+
-+Table *luaH_new (lua_State *L, int narray, int nhash) {
-+ Table *t = luaM_new(L, Table);
-+ luaC_link(L, obj2gco(t), LUA_TTABLE);
-+ t->metatable = NULL;
-+ t->flags = cast_byte(~0);
-+ /* temporary values (kept only if some malloc fails) */
-+ t->array = NULL;
-+ t->sizearray = 0;
-+ t->lsizenode = 0;
-+ t->node = cast(Node *, dummynode);
-+ setarrayvector(L, t, narray);
-+ setnodevector(L, t, nhash);
-+ return t;
-+}
-+
-+
-+void luaH_free (lua_State *L, Table *t) {
-+ if (t->node != dummynode)
-+ luaM_freearray(L, t->node, sizenode(t), Node);
-+ luaM_freearray(L, t->array, t->sizearray, TValue);
-+ luaM_free(L, t);
-+}
-+
-+
-+static Node *getfreepos (Table *t) {
-+ while (t->lastfree-- > t->node) {
-+ if (ttisnil(gkey(t->lastfree)))
-+ return t->lastfree;
-+ }
-+ return NULL; /* could not find a free place */
-+}
-+
-+
-+
-+/*
-+** inserts a new key into a hash table; first, check whether key's main
-+** position is free. If not, check whether colliding node is in its main
-+** position or not: if it is not, move colliding node to an empty place and
-+** put new key in its main position; otherwise (colliding node is in its main
-+** position), new key goes to an empty position.
-+*/
-+static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
-+ Node *mp = mainposition(t, key);
-+ if (!ttisnil(gval(mp)) || mp == dummynode) {
-+ Node *othern;
-+ Node *n = getfreepos(t); /* get a free place */
-+ if (n == NULL) { /* cannot find a free place? */
-+ rehash(L, t, key); /* grow table */
-+ return luaH_set(L, t, key); /* re-insert key into grown table */
-+ }
-+ lua_assert(n != dummynode);
-+ othern = mainposition(t, key2tval(mp));
-+ if (othern != mp) { /* is colliding node out of its main position? */
-+ /* yes; move colliding node into free position */
-+ while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
-+ gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
-+ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
-+ gnext(mp) = NULL; /* now `mp' is free */
-+ setnilvalue(gval(mp));
-+ }
-+ else { /* colliding node is in its own main position */
-+ /* new node will go into free position */
-+ gnext(n) = gnext(mp); /* chain new position */
-+ gnext(mp) = n;
-+ mp = n;
-+ }
-+ }
-+ gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
-+ luaC_barriert(L, t, key);
-+ lua_assert(ttisnil(gval(mp)));
-+ return gval(mp);
-+}
-+
-+
-+/*
-+** search function for integers
-+*/
-+const TValue *luaH_getnum (Table *t, int key) {
-+ /* (1 <= key && key <= t->sizearray) */
-+ if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
-+ return &t->array[key-1];
-+ else {
-+ lua_Number nk = cast_num(key);
-+ Node *n = hashnum(t, nk);
-+ do { /* check whether `key' is somewhere in the chain */
-+ if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
-+ return gval(n); /* that's it */
-+ else n = gnext(n);
-+ } while (n);
-+ return luaO_nilobject;
-+ }
-+}
-+
-+
-+/*
-+** search function for strings
-+*/
-+const TValue *luaH_getstr (Table *t, TString *key) {
-+ Node *n = hashstr(t, key);
-+ do { /* check whether `key' is somewhere in the chain */
-+ if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
-+ return gval(n); /* that's it */
-+ else n = gnext(n);
-+ } while (n);
-+ return luaO_nilobject;
-+}
-+
-+
-+/*
-+** main search function
-+*/
-+const TValue *luaH_get (Table *t, const TValue *key) {
-+ switch (ttype(key)) {
-+ case LUA_TNIL: return luaO_nilobject;
-+ case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
-+ case LUA_TNUMBER: {
-+ int k;
-+ lua_Number n = nvalue(key);
-+ lua_number2int(k, n);
-+ if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
-+ return luaH_getnum(t, k); /* use specialized version */
-+ /* else go through */
-+ }
-+ default: {
-+ Node *n = mainposition(t, key);
-+ do { /* check whether `key' is somewhere in the chain */
-+ if (luaO_rawequalObj(key2tval(n), key))
-+ return gval(n); /* that's it */
-+ else n = gnext(n);
-+ } while (n);
-+ return luaO_nilobject;
-+ }
-+ }
-+}
-+
-+
-+TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
-+ const TValue *p = luaH_get(t, key);
-+ t->flags = 0;
-+ if (p != luaO_nilobject)
-+ return cast(TValue *, p);
-+ else {
-+ if (ttisnil(key)) luaG_runerror(L, "table index is nil");
-+ else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
-+ luaG_runerror(L, "table index is NaN");
-+ return newkey(L, t, key);
-+ }
-+}
-+
-+
-+TValue *luaH_setnum (lua_State *L, Table *t, int key) {
-+ const TValue *p = luaH_getnum(t, key);
-+ if (p != luaO_nilobject)
-+ return cast(TValue *, p);
-+ else {
-+ TValue k;
-+ setnvalue(&k, cast_num(key));
-+ return newkey(L, t, &k);
-+ }
-+}
-+
-+
-+TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
-+ const TValue *p = luaH_getstr(t, key);
-+ if (p != luaO_nilobject)
-+ return cast(TValue *, p);
-+ else {
-+ TValue k;
-+ setsvalue(L, &k, key);
-+ return newkey(L, t, &k);
-+ }
-+}
-+
-+
-+static int unbound_search (Table *t, unsigned int j) {
-+ unsigned int i = j; /* i is zero or a present index */
-+ j++;
-+ /* find `i' and `j' such that i is present and j is not */
-+ while (!ttisnil(luaH_getnum(t, j))) {
-+ i = j;
-+ j *= 2;
-+ if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
-+ /* table was built with bad purposes: resort to linear search */
-+ i = 1;
-+ while (!ttisnil(luaH_getnum(t, i))) i++;
-+ return i - 1;
-+ }
-+ }
-+ /* now do a binary search between them */
-+ while (j - i > 1) {
-+ unsigned int m = (i+j)/2;
-+ if (ttisnil(luaH_getnum(t, m))) j = m;
-+ else i = m;
-+ }
-+ return i;
-+}
-+
-+
-+/*
-+** Try to find a boundary in table `t'. A `boundary' is an integer index
-+** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
-+*/
-+int luaH_getn (Table *t) {
-+ unsigned int j = t->sizearray;
-+ if (j > 0 && ttisnil(&t->array[j - 1])) {
-+ /* there is a boundary in the array part: (binary) search for it */
-+ unsigned int i = 0;
-+ while (j - i > 1) {
-+ unsigned int m = (i+j)/2;
-+ if (ttisnil(&t->array[m - 1])) j = m;
-+ else i = m;
-+ }
-+ return i;
-+ }
-+ /* else must find a boundary in hash part */
-+ else if (t->node == dummynode) /* hash part is empty? */
-+ return j; /* that is easy... */
-+ else return unbound_search(t, j);
-+}
-+
-+
-+
-+#if defined(LUA_DEBUG)
-+
-+Node *luaH_mainposition (const Table *t, const TValue *key) {
-+ return mainposition(t, key);
-+}
-+
-+int luaH_isdummy (Node *n) { return n == dummynode; }
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/lua/ltable.h
-@@ -0,0 +1,40 @@
-+/*
-+** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $
-+** Lua tables (hash)
-+** See Copyright Notice in lua.h
-+*/
-+
-+#ifndef ltable_h
-+#define ltable_h
-+
-+#include "lobject.h"
-+
-+
-+#define gnode(t,i) (&(t)->node[i])
-+#define gkey(n) (&(n)->i_key.nk)
-+#define gval(n) (&(n)->i_val)
-+#define gnext(n) ((n)->i_key.nk.next)
-+
-+#define key2tval(n) (&(n)->i_key.tvk)
-+
-+
-+LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
-+LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
-+LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
-+LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
-+LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
-+LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
-+LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
-+LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
-+LUAI_FUNC void luaH_free (lua_State *L, Table *t);
-+LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
-+LUAI_FUNC int luaH_getn (Table *t);
-+
-+
-+#if defined(LUA_DEBUG)
-+LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
-+LUAI_FUNC int luaH_isdummy (Node *n);
-+#endif
-+
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/lua/ltablib.c
-@@ -0,0 +1,288 @@
-+/*
-+** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $
-+** Library for Table Manipulation
-+** See Copyright Notice in lua.h
-+*/
-+
-+
-+#include
-+
-+#define ltablib_c
-+#define LUA_LIB
-+
-+#include "lua.h"
-+
-+#include "lauxlib.h"
-+#include "lualib.h"
-+
-+
-+#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
-+
-+
-+static int foreachi (lua_State *L) {
-+ int i;
-+ int n = aux_getn(L, 1);
-+ luaL_checktype(L, 2, LUA_TFUNCTION);
-+ for (i=1; i <= n; i++) {
-+ lua_pushvalue(L, 2); /* function */
-+ lua_pushinteger(L, i); /* 1st argument */
-+ lua_rawgeti(L, 1, i); /* 2nd argument */
-+ lua_call(L, 2, 1);
-+ if (!lua_isnil(L, -1))
-+ return 1;
-+ lua_pop(L, 1); /* remove nil result */
-+ }
-+ return 0;
-+}
-+
-+
-+static int foreach (lua_State *L) {
-+ luaL_checktype(L, 1, LUA_TTABLE);
-+ luaL_checktype(L, 2, LUA_TFUNCTION);
-+ lua_pushnil(L); /* first key */
-+ while (lua_next(L, 1)) {
-+ lua_pushvalue(L, 2); /* function */
-+ lua_pushvalue(L, -3); /* key */
-+ lua_pushvalue(L, -3); /* value */
-+ lua_call(L, 2, 1);
-+ if (!lua_isnil(L, -1))
-+ return 1;
-+ lua_pop(L, 2); /* remove value and result */
-+ }
-+ return 0;
-+}
-+
-+
-+static int maxn (lua_State *L) {
-+ lua_Number max = 0;
-+ luaL_checktype(L, 1, LUA_TTABLE);
-+ lua_pushnil(L); /* first key */
-+ while (lua_next(L, 1)) {
-+ lua_pop(L, 1); /* remove value */
-+ if (lua_type(L, -1) == LUA_TNUMBER) {
-+ lua_Number v = lua_tonumber(L, -1);
-+ if (v > max) max = v;
-+ }
-+ }
-+ lua_pushnumber(L, max);
-+ return 1;
-+}
-+
-+
-+static int getn (lua_State *L) {
-+ lua_pushinteger(L, aux_getn(L, 1));
-+ return 1;
-+}
-+
-+
-+static int setn (lua_State *L) {
-+ luaL_checktype(L, 1, LUA_TTABLE);
-+#ifndef luaL_setn
-+ luaL_setn(L, 1, luaL_checkint(L, 2));
-+#else
-+ luaL_error(L, LUA_QL("setn") " is obsolete");
-+#endif
-+ lua_pushvalue(L, 1);
-+ return 1;
-+}
-+
-+
-+static int tinsert (lua_State *L) {
-+ int e = aux_getn(L, 1) + 1; /* first empty element */
-+ int pos; /* where to insert new element */
-+ switch (lua_gettop(L)) {
-+ case 2: { /* called with only 2 arguments */
-+ pos = e; /* insert new element at the end */
-+ break;
-+ }
-+ case 3: {
-+ int i;
-+ pos = luaL_checkint(L, 2); /* 2nd argument is the position */
-+ if (pos > e) e = pos; /* `grow' array if necessary */
-+ for (i = e; i > pos; i--) { /* move up elements */
-+ lua_rawgeti(L, 1, i-1);
-+ lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
-+ }
-+ break;
-+ }
-+ default: {
-+ return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
-+ }
-+ }
-+ luaL_setn(L, 1, e); /* new size */
-+ lua_rawseti(L, 1, pos); /* t[pos] = v */
-+ return 0;
-+}
-+
-+
-+static int tremove (lua_State *L) {
-+ int e = aux_getn(L, 1);
-+ int pos = luaL_optint(L, 2, e);
-+ if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
-+ return 0; /* nothing to remove */
-+ luaL_setn(L, 1, e - 1); /* t.n = n-1 */
-+ lua_rawgeti(L, 1, pos); /* result = t[pos] */
-+ for ( ;pos= P */
-+ while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
-+ if (i>u) luaL_error(L, "invalid order function for sorting");
-+ lua_pop(L, 1); /* remove a[i] */
-+ }
-+ /* repeat --j until a[j] <= P */
-+ while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
-+ if (j
-+
-+#define ltm_c
-+#define LUA_CORE
-+
-+#include "lua.h"
-+
-+#include "lobject.h"
-+#include "lstate.h"
-+#include "lstring.h"
-+#include "ltable.h"
-+#include "ltm.h"
-+
-+
-+
-+const char *const luaT_typenames[] = {
-+ "nil", "boolean", "userdata", "number",
-+ "string", "table", "function", "userdata", "thread",
-+ "proto", "upval"
-+};
-+
-+
-+void luaT_init (lua_State *L) {
-+ static const char *const luaT_eventname[] = { /* ORDER TM */
-+ "__index", "__newindex",
-+ "__gc", "__mode", "__eq",
-+ "__add", "__sub", "__mul", "__div", "__mod",
-+ "__pow", "__unm", "__len", "__lt", "__le",
-+ "__concat", "__call"
-+ };
-+ int i;
-+ for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]);
-+ luaS_fix(G(L)->tmname[i]); /* never collect these names */
-+ }
-+}
-+
-+
-+/*
-+** function to be used with macro "fasttm": optimized for absence of
-+** tag methods
-+*/
-+const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
-+ const TValue *tm = luaH_getstr(events, ename);
-+ lua_assert(event <= TM_EQ);
-+ if (ttisnil(tm)) { /* no tag method? */
-+ events->flags |= cast_byte(1u<metatable;
-+ break;
-+ case LUA_TUSERDATA:
-+ mt = uvalue(o)->metatable;
-+ break;
-+ default:
-+ mt = G(L)->mt[ttype(o)];
-+ }
-+ return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
-+}
-+
---- /dev/null
-+++ b/extensions/LUA/lua/ltm.h
-@@ -0,0 +1,54 @@
-+/*
-+** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $
-+** Tag methods
-+** See Copyright Notice in lua.h
-+*/
-+
-+#ifndef ltm_h
-+#define ltm_h
-+
-+
-+#include "lobject.h"
-+
-+
-+/*
-+* WARNING: if you change the order of this enumeration,
-+* grep "ORDER TM"
-+*/
-+typedef enum {
-+ TM_INDEX,
-+ TM_NEWINDEX,
-+ TM_GC,
-+ TM_MODE,
-+ TM_EQ, /* last tag method with `fast' access */
-+ TM_ADD,
-+ TM_SUB,
-+ TM_MUL,
-+ TM_DIV,
-+ TM_MOD,
-+ TM_POW,
-+ TM_UNM,
-+ TM_LEN,
-+ TM_LT,
-+ TM_LE,
-+ TM_CONCAT,
-+ TM_CALL,
-+ TM_N /* number of elements in the enum */
-+} TMS;
-+
-+
-+
-+#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
-+ ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
-+
-+#define fasttm(l,et,e) gfasttm(G(l), et, e)
-+
-+LUAI_DATA const char *const luaT_typenames[];
-+
-+
-+LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
-+LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
-+ TMS event);
-+LUAI_FUNC void luaT_init (lua_State *L);
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/lua/luaconf.h
-@@ -0,0 +1,797 @@
-+/*
-+** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $
-+** Configuration file for Lua
-+** See Copyright Notice in lua.h
-+*/
-+
-+
-+#ifndef lconfig_h
-+#define lconfig_h
-+
-+#include
-+
-+#if !defined(__KERNEL__)
-+#include
-+#else
-+#define UCHAR_MAX 255
-+#define SHRT_MAX 32767
-+#define BUFSIZ 8192
-+#define NO_FPU
-+#endif
-+
-+/*
-+** ==================================================================
-+** Search for "@@" to find all configurable definitions.
-+** ===================================================================
-+*/
-+
-+
-+/*
-+@@ LUA_ANSI controls the use of non-ansi features.
-+** CHANGE it (define it) if you want Lua to avoid the use of any
-+** non-ansi feature or library.
-+*/
-+#if defined(__STRICT_ANSI__)
-+#define LUA_ANSI
-+#endif
-+
-+
-+#if !defined(LUA_ANSI) && defined(_WIN32)
-+#define LUA_WIN
-+#endif
-+
-+#if defined(LUA_USE_LINUX)
-+#define LUA_USE_POSIX
-+#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
-+#define LUA_USE_READLINE /* needs some extra libraries */
-+#endif
-+
-+#if defined(LUA_USE_MACOSX)
-+#define LUA_USE_POSIX
-+#define LUA_DL_DYLD /* does not need extra library */
-+#endif
-+
-+
-+
-+/*
-+@@ LUA_USE_POSIX includes all functionallity listed as X/Open System
-+@* Interfaces Extension (XSI).
-+** CHANGE it (define it) if your system is XSI compatible.
-+*/
-+#if defined(LUA_USE_POSIX)
-+#define LUA_USE_MKSTEMP
-+#define LUA_USE_ISATTY
-+#define LUA_USE_POPEN
-+#define LUA_USE_ULONGJMP
-+#endif
-+
-+
-+/*
-+@@ LUA_PATH and LUA_CPATH are the names of the environment variables that
-+@* Lua check to set its paths.
-+@@ LUA_INIT is the name of the environment variable that Lua
-+@* checks for initialization code.
-+** CHANGE them if you want different names.
-+*/
-+#define LUA_PATH "LUA_PATH"
-+#define LUA_CPATH "LUA_CPATH"
-+#define LUA_INIT "LUA_INIT"
-+
-+
-+/*
-+@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
-+@* Lua libraries.
-+@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
-+@* C libraries.
-+** CHANGE them if your machine has a non-conventional directory
-+** hierarchy or if you want to install your libraries in
-+** non-conventional directories.
-+*/
-+#if defined(_WIN32)
-+/*
-+** In Windows, any exclamation mark ('!') in the path is replaced by the
-+** path of the directory of the executable file of the current process.
-+*/
-+#define LUA_LDIR "!\\lua\\"
-+#define LUA_CDIR "!\\"
-+#define LUA_PATH_DEFAULT \
-+ ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
-+ LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua"
-+#define LUA_CPATH_DEFAULT \
-+ ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
-+
-+#else
-+#define LUA_ROOT "/usr/local/"
-+#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
-+#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
-+#define LUA_PATH_DEFAULT \
-+ "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
-+ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
-+#define LUA_CPATH_DEFAULT \
-+ "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
-+#endif
-+
-+
-+/*
-+@@ LUA_DIRSEP is the directory separator (for submodules).
-+** CHANGE it if your machine does not use "/" as the directory separator
-+** and is not Windows. (On Windows Lua automatically uses "\".)
-+*/
-+#if defined(_WIN32)
-+#define LUA_DIRSEP "\\"
-+#else
-+#define LUA_DIRSEP "/"
-+#endif
-+
-+
-+/*
-+@@ LUA_PATHSEP is the character that separates templates in a path.
-+@@ LUA_PATH_MARK is the string that marks the substitution points in a
-+@* template.
-+@@ LUA_EXECDIR in a Windows path is replaced by the executable's
-+@* directory.
-+@@ LUA_IGMARK is a mark to ignore all before it when bulding the
-+@* luaopen_ function name.
-+** CHANGE them if for some reason your system cannot use those
-+** characters. (E.g., if one of those characters is a common character
-+** in file/directory names.) Probably you do not need to change them.
-+*/
-+#define LUA_PATHSEP ";"
-+#define LUA_PATH_MARK "?"
-+#define LUA_EXECDIR "!"
-+#define LUA_IGMARK "-"
-+
-+
-+/*
-+@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
-+** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
-+** machines, ptrdiff_t gives a good choice between int or long.)
-+*/
-+#define LUA_INTEGER ptrdiff_t
-+
-+
-+/*
-+@@ LUA_API is a mark for all core API functions.
-+@@ LUALIB_API is a mark for all standard library functions.
-+** CHANGE them if you need to define those functions in some special way.
-+** For instance, if you want to create one Windows DLL with the core and
-+** the libraries, you may want to use the following definition (define
-+** LUA_BUILD_AS_DLL to get it).
-+*/
-+#if defined(LUA_BUILD_AS_DLL)
-+
-+#if defined(LUA_CORE) || defined(LUA_LIB)
-+#define LUA_API __declspec(dllexport)
-+#else
-+#define LUA_API __declspec(dllimport)
-+#endif
-+
-+#else
-+
-+#define LUA_API extern
-+
-+#endif
-+
-+/* more often than not the libs go together with the core */
-+#define LUALIB_API LUA_API
-+
-+
-+/*
-+@@ LUAI_FUNC is a mark for all extern functions that are not to be
-+@* exported to outside modules.
-+@@ LUAI_DATA is a mark for all extern (const) variables that are not to
-+@* be exported to outside modules.
-+** CHANGE them if you need to mark them in some special way. Elf/gcc
-+** (versions 3.2 and later) mark them as "hidden" to optimize access
-+** when Lua is compiled as a shared library.
-+*/
-+#if defined(luaall_c)
-+#define LUAI_FUNC static
-+#define LUAI_DATA /* empty */
-+
-+#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
-+ defined(__ELF__)
-+#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
-+#define LUAI_DATA LUAI_FUNC
-+
-+#else
-+#define LUAI_FUNC extern
-+#define LUAI_DATA extern
-+#endif
-+
-+
-+
-+/*
-+@@ LUA_QL describes how error messages quote program elements.
-+** CHANGE it if you want a different appearance.
-+*/
-+#define LUA_QL(x) "'" x "'"
-+#define LUA_QS LUA_QL("%s")
-+
-+
-+/*
-+@@ LUA_IDSIZE gives the maximum size for the description of the source
-+@* of a function in debug information.
-+** CHANGE it if you want a different size.
-+*/
-+#define LUA_IDSIZE 60
-+
-+
-+/*
-+** {==================================================================
-+** Stand-alone configuration
-+** ===================================================================
-+*/
-+
-+#if defined(lua_c) || defined(luaall_c)
-+
-+/*
-+@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that
-+@* is, whether we're running lua interactively).
-+** CHANGE it if you have a better definition for non-POSIX/non-Windows
-+** systems.
-+*/
-+#if defined(LUA_USE_ISATTY)
-+#include
-+#define lua_stdin_is_tty() isatty(0)
-+#elif defined(LUA_WIN)
-+#include
-+#include
-+#define lua_stdin_is_tty() _isatty(_fileno(stdin))
-+#else
-+#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
-+#endif
-+
-+
-+/*
-+@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
-+@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
-+** CHANGE them if you want different prompts. (You can also change the
-+** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
-+*/
-+#define LUA_PROMPT "> "
-+#define LUA_PROMPT2 ">> "
-+
-+
-+/*
-+@@ LUA_PROGNAME is the default name for the stand-alone Lua program.
-+** CHANGE it if your stand-alone interpreter has a different name and
-+** your system is not able to detect that name automatically.
-+*/
-+#define LUA_PROGNAME "lua"
-+
-+
-+/*
-+@@ LUA_MAXINPUT is the maximum length for an input line in the
-+@* stand-alone interpreter.
-+** CHANGE it if you need longer lines.
-+*/
-+#define LUA_MAXINPUT 512
-+
-+
-+/*
-+@@ lua_readline defines how to show a prompt and then read a line from
-+@* the standard input.
-+@@ lua_saveline defines how to "save" a read line in a "history".
-+@@ lua_freeline defines how to free a line read by lua_readline.
-+** CHANGE them if you want to improve this functionality (e.g., by using
-+** GNU readline and history facilities).
-+*/
-+#if defined(LUA_USE_READLINE)
-+#include
-+#include
-+#include
-+#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
-+#define lua_saveline(L,idx) \
-+ if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
-+ add_history(lua_tostring(L, idx)); /* add it to history */
-+#define lua_freeline(L,b) ((void)L, free(b))
-+#else
-+#define lua_readline(L,b,p) \
-+ ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
-+ fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
-+#define lua_saveline(L,idx) { (void)L; (void)idx; }
-+#define lua_freeline(L,b) { (void)L; (void)b; }
-+#endif
-+
-+#endif
-+
-+/* }================================================================== */
-+
-+
-+/*
-+@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
-+@* as a percentage.
-+** CHANGE it if you want the GC to run faster or slower (higher values
-+** mean larger pauses which mean slower collection.) You can also change
-+** this value dynamically.
-+*/
-+#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */
-+
-+
-+/*
-+@@ LUAI_GCMUL defines the default speed of garbage collection relative to
-+@* memory allocation as a percentage.
-+** CHANGE it if you want to change the granularity of the garbage
-+** collection. (Higher values mean coarser collections. 0 represents
-+** infinity, where each step performs a full collection.) You can also
-+** change this value dynamically.
-+*/
-+#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
-+
-+
-+
-+/*
-+@@ LUA_COMPAT_GETN controls compatibility with old getn behavior.
-+** CHANGE it (define it) if you want exact compatibility with the
-+** behavior of setn/getn in Lua 5.0.
-+*/
-+#undef LUA_COMPAT_GETN
-+
-+/*
-+@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
-+** CHANGE it to undefined as soon as you do not need a global 'loadlib'
-+** function (the function is still available as 'package.loadlib').
-+*/
-+#undef LUA_COMPAT_LOADLIB
-+
-+/*
-+@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
-+** CHANGE it to undefined as soon as your programs use only '...' to
-+** access vararg parameters (instead of the old 'arg' table).
-+*/
-+#define LUA_COMPAT_VARARG
-+
-+/*
-+@@ LUA_COMPAT_MOD controls compatibility with old math.mod function.
-+** CHANGE it to undefined as soon as your programs use 'math.fmod' or
-+** the new '%' operator instead of 'math.mod'.
-+*/
-+#define LUA_COMPAT_MOD
-+
-+/*
-+@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
-+@* facility.
-+** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
-+** off the advisory error when nesting [[...]].
-+*/
-+#define LUA_COMPAT_LSTR 1
-+
-+/*
-+@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name.
-+** CHANGE it to undefined as soon as you rename 'string.gfind' to
-+** 'string.gmatch'.
-+*/
-+#define LUA_COMPAT_GFIND
-+
-+/*
-+@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib'
-+@* behavior.
-+** CHANGE it to undefined as soon as you replace to 'luaL_register'
-+** your uses of 'luaL_openlib'
-+*/
-+#define LUA_COMPAT_OPENLIB
-+
-+
-+
-+/*
-+@@ luai_apicheck is the assert macro used by the Lua-C API.
-+** CHANGE luai_apicheck if you want Lua to perform some checks in the
-+** parameters it gets from API calls. This may slow down the interpreter
-+** a bit, but may be quite useful when debugging C code that interfaces
-+** with Lua. A useful redefinition is to use assert.h.
-+*/
-+#if defined(LUA_USE_APICHECK)
-+#include
-+#define luai_apicheck(L,o) { (void)L; assert(o); }
-+#else
-+#define luai_apicheck(L,o) { (void)L; }
-+#endif
-+
-+
-+/*
-+@@ LUAI_BITSINT defines the number of bits in an int.
-+** CHANGE here if Lua cannot automatically detect the number of bits of
-+** your machine. Probably you do not need to change this.
-+*/
-+/* avoid overflows in comparison */
-+#if !defined(__KERNEL__)
-+#include
-+#define LUA_INT_MAX INT_MAX
-+#else
-+#define LUA_INT_MAX (~0U>>1)
-+#endif
-+
-+#if LUA_INT_MAX-20 < 32760
-+#define LUAI_BITSINT 16
-+#elif LUA_INT_MAX > 2147483640L
-+/* int has at least 32 bits */
-+#define LUAI_BITSINT 32
-+#else
-+#error "you must define LUA_BITSINT with number of bits in an integer"
-+#endif
-+
-+
-+/*
-+@@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
-+@@ LUAI_INT32 is an signed integer with at least 32 bits.
-+@@ LUAI_UMEM is an unsigned integer big enough to count the total
-+@* memory used by Lua.
-+@@ LUAI_MEM is a signed integer big enough to count the total memory
-+@* used by Lua.
-+** CHANGE here if for some weird reason the default definitions are not
-+** good enough for your machine. (The definitions in the 'else'
-+** part always works, but may waste space on machines with 64-bit
-+** longs.) Probably you do not need to change this.
-+*/
-+#if LUAI_BITSINT >= 32
-+#define LUAI_UINT32 unsigned int
-+#define LUAI_INT32 int
-+#define LUAI_MAXINT32 INT_MAX
-+#define LUAI_UMEM size_t
-+#define LUAI_MEM ptrdiff_t
-+#else
-+/* 16-bit ints */
-+#define LUAI_UINT32 unsigned long
-+#define LUAI_INT32 long
-+#define LUAI_MAXINT32 LONG_MAX
-+#define LUAI_UMEM unsigned long
-+#define LUAI_MEM long
-+#endif
-+
-+
-+/*
-+@@ LUAI_MAXCALLS limits the number of nested calls.
-+** CHANGE it if you need really deep recursive calls. This limit is
-+** arbitrary; its only purpose is to stop infinite recursion before
-+** exhausting memory.
-+*/
-+#define LUAI_MAXCALLS 20000
-+
-+
-+/*
-+@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
-+@* can use.
-+** CHANGE it if you need lots of (Lua) stack space for your C
-+** functions. This limit is arbitrary; its only purpose is to stop C
-+** functions to consume unlimited stack space. (must be smaller than
-+** -LUA_REGISTRYINDEX)
-+*/
-+#define LUAI_MAXCSTACK 8000
-+
-+
-+
-+/*
-+** {==================================================================
-+** CHANGE (to smaller values) the following definitions if your system
-+** has a small C stack. (Or you may want to change them to larger
-+** values if your system has a large C stack and these limits are
-+** too rigid for you.) Some of these constants control the size of
-+** stack-allocated arrays used by the compiler or the interpreter, while
-+** others limit the maximum number of recursive calls that the compiler
-+** or the interpreter can perform. Values too large may cause a C stack
-+** overflow for some forms of deep constructs.
-+** ===================================================================
-+*/
-+
-+
-+/*
-+@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and
-+@* syntactical nested non-terminals in a program.
-+*/
-+#define LUAI_MAXCCALLS 200
-+
-+
-+/*
-+@@ LUAI_MAXVARS is the maximum number of local variables per function
-+@* (must be smaller than 250).
-+*/
-+#define LUAI_MAXVARS 200
-+
-+
-+/*
-+@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
-+@* (must be smaller than 250).
-+*/
-+#define LUAI_MAXUPVALUES 60
-+
-+
-+/*
-+@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
-+*/
-+#define LUAL_BUFFERSIZE BUFSIZ
-+
-+/* }================================================================== */
-+
-+
-+
-+
-+/*
-+** {==================================================================
-+@@ LUA_NUMBER is the type of numbers in Lua.
-+** CHANGE the following definitions only if you want to build Lua
-+** with a number type different from double. You may also need to
-+** change lua_number2int & lua_number2integer.
-+** ===================================================================
-+*/
-+#if !defined(NO_FPU)
-+#define LUA_NUMBER_DOUBLE
-+#define LUA_NUMBER double
-+#else
-+#define LUA_NUMBER long
-+#endif
-+
-+/*
-+@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
-+@* over a number.
-+*/
-+#define LUAI_UACNUMBER LUA_NUMBER
-+
-+
-+/*
-+@@ LUA_NUMBER_SCAN is the format for reading numbers.
-+@@ LUA_NUMBER_FMT is the format for writing numbers.
-+@@ lua_number2str converts a number to a string.
-+@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
-+@@ lua_str2number converts a string to a number.
-+*/
-+#if !defined(NO_FPU)
-+#define LUA_NUMBER_SCAN "%lf"
-+#define LUA_NUMBER_FMT "%.14g"
-+#define lua_str2number(s,p) strtod((s), (p))
-+#else
-+#define LUA_NUMBER_SCAN "%ld"
-+#define LUA_NUMBER_FMT "%ld"
-+#if !defined(__KERNEL__)
-+#define lua_str2number(s,p) strtol((s), (p), 10)
-+#else
-+#define lua_str2number(s,p) simple_strtol((s), (p), 10)
-+#endif
-+#endif
-+
-+#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
-+#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
-+
-+/*
-+@@ The luai_num* macros define the primitive operations over numbers.
-+*/
-+#if defined(LUA_CORE)
-+#define luai_numadd(a,b) ((a)+(b))
-+#define luai_numsub(a,b) ((a)-(b))
-+#define luai_nummul(a,b) ((a)*(b))
-+#define luai_numdiv(a,b) ((a)/(b))
-+#define luai_numunm(a) (-(a))
-+#define luai_numeq(a,b) ((a)==(b))
-+#define luai_numlt(a,b) ((a)<(b))
-+#define luai_numle(a,b) ((a)<=(b))
-+#define luai_numisnan(a) (!luai_numeq((a), (a)))
-+#if !defined(NO_FPU)
-+#include
-+#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
-+#define luai_numpow(a,b) (pow(a,b))
-+#else
-+#define luai_nummod(a,b) ((a)%(b))
-+#define luai_numpow(a,b) luai_nummul(a,b)
-+#endif
-+#endif
-+
-+
-+/*
-+@@ lua_number2int is a macro to convert lua_Number to int.
-+@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
-+** CHANGE them if you know a faster way to convert a lua_Number to
-+** int (with any rounding method and without throwing errors) in your
-+** system. In Pentium machines, a naive typecast from double to int
-+** in C is extremely slow, so any alternative is worth trying.
-+*/
-+
-+/* On a Pentium, resort to a trick */
-+#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
-+ (defined(__i386) || defined (_M_IX86) || defined(__i386__))
-+
-+/* On a Microsoft compiler, use assembler */
-+#if defined(_MSC_VER)
-+
-+#define lua_number2int(i,d) __asm fld d __asm fistp i
-+#define lua_number2integer(i,n) lua_number2int(i, n)
-+
-+/* the next trick should work on any Pentium, but sometimes clashes
-+ with a DirectX idiosyncrasy */
-+#else
-+
-+union luai_Cast { double l_d; long l_l; };
-+#define lua_number2int(i,d) \
-+ { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
-+#define lua_number2integer(i,n) lua_number2int(i, n)
-+
-+#endif
-+
-+
-+/* this option always works, but may be slow */
-+#else
-+#define lua_number2int(i,d) ((i)=(int)(d))
-+#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
-+
-+#endif
-+
-+/* }================================================================== */
-+
-+
-+/*
-+@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
-+** CHANGE it if your system requires alignments larger than double. (For
-+** instance, if your system supports long doubles and they must be
-+** aligned in 16-byte boundaries, then you should add long double in the
-+** union.) Probably you do not need to change this.
-+*/
-+#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
-+
-+
-+/*
-+@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
-+** CHANGE them if you prefer to use longjmp/setjmp even with C++
-+** or if want/don't to use _longjmp/_setjmp instead of regular
-+** longjmp/setjmp. By default, Lua handles errors with exceptions when
-+** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
-+** and with longjmp/setjmp otherwise.
-+*/
-+#if defined(__KERNEL__)
-+#undef LUA_USE_ULONGJMP
-+#endif
-+
-+#if defined(__cplusplus)
-+/* C++ exceptions */
-+#define LUAI_THROW(L,c) throw(c)
-+#define LUAI_TRY(L,c,a) try { a } catch(...) \
-+ { if ((c)->status == 0) (c)->status = -1; }
-+#define luai_jmpbuf int /* dummy variable */
-+
-+#elif defined(LUA_USE_ULONGJMP)
-+/* in Unix, try _longjmp/_setjmp (more efficient) */
-+#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
-+#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
-+#define luai_jmpbuf jmp_buf
-+
-+#else
-+/* default handling with long jumps */
-+#define LUAI_THROW(L,c) longjmp((c)->b, 1)
-+#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
-+#define luai_jmpbuf jmp_buf
-+
-+#endif
-+
-+
-+/*
-+@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern
-+@* can do during pattern-matching.
-+** CHANGE it if you need more captures. This limit is arbitrary.
-+*/
-+#define LUA_MAXCAPTURES 32
-+
-+
-+/*
-+@@ lua_tmpnam is the function that the OS library uses to create a
-+@* temporary name.
-+@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam.
-+** CHANGE them if you have an alternative to tmpnam (which is considered
-+** insecure) or if you want the original tmpnam anyway. By default, Lua
-+** uses tmpnam except when POSIX is available, where it uses mkstemp.
-+*/
-+#if defined(loslib_c) || defined(luaall_c)
-+
-+#if defined(LUA_USE_MKSTEMP)
-+#include
-+#define LUA_TMPNAMBUFSIZE 32
-+#define lua_tmpnam(b,e) { \
-+ strcpy(b, "/tmp/lua_XXXXXX"); \
-+ e = mkstemp(b); \
-+ if (e != -1) close(e); \
-+ e = (e == -1); }
-+
-+#else
-+#define LUA_TMPNAMBUFSIZE L_tmpnam
-+#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
-+#endif
-+
-+#endif
-+
-+
-+/*
-+@@ lua_popen spawns a new process connected to the current one through
-+@* the file streams.
-+** CHANGE it if you have a way to implement it in your system.
-+*/
-+#if defined(LUA_USE_POPEN)
-+
-+#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
-+#define lua_pclose(L,file) ((void)L, (pclose(file) != -1))
-+
-+#elif defined(LUA_WIN)
-+
-+#define lua_popen(L,c,m) ((void)L, _popen(c,m))
-+#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1))
-+
-+#else
-+
-+#define lua_popen(L,c,m) ((void)((void)c, m), \
-+ luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
-+#define lua_pclose(L,file) ((void)((void)L, file), 0)
-+
-+#endif
-+
-+/*
-+@@ LUA_DL_* define which dynamic-library system Lua should use.
-+** CHANGE here if Lua has problems choosing the appropriate
-+** dynamic-library system for your platform (either Windows' DLL, Mac's
-+** dyld, or Unix's dlopen). If your system is some kind of Unix, there
-+** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for
-+** it. To use dlopen you also need to adapt the src/Makefile (probably
-+** adding -ldl to the linker options), so Lua does not select it
-+** automatically. (When you change the makefile to add -ldl, you must
-+** also add -DLUA_USE_DLOPEN.)
-+** If you do not want any kind of dynamic library, undefine all these
-+** options.
-+** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD.
-+*/
-+#if defined(LUA_USE_DLOPEN)
-+#define LUA_DL_DLOPEN
-+#endif
-+
-+#if defined(LUA_WIN)
-+#define LUA_DL_DLL
-+#endif
-+
-+
-+/*
-+@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State
-+@* (the data goes just *before* the lua_State pointer).
-+** CHANGE (define) this if you really need that. This value must be
-+** a multiple of the maximum alignment required for your machine.
-+*/
-+#define LUAI_EXTRASPACE 0
-+
-+
-+/*
-+@@ luai_userstate* allow user-specific actions on threads.
-+** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
-+** extra when a thread is created/deleted/resumed/yielded.
-+*/
-+#define luai_userstateopen(L) ((void)L)
-+#define luai_userstateclose(L) ((void)L)
-+#define luai_userstatethread(L,L1) ((void)L)
-+#define luai_userstatefree(L) ((void)L)
-+#define luai_userstateresume(L,n) ((void)L)
-+#define luai_userstateyield(L,n) ((void)L)
-+
-+
-+/*
-+@@ LUA_INTFRMLEN is the length modifier for integer conversions
-+@* in 'string.format'.
-+@@ LUA_INTFRM_T is the integer type correspoding to the previous length
-+@* modifier.
-+** CHANGE them if your system supports long long or does not support long.
-+*/
-+
-+#if defined(LUA_USELONGLONG)
-+
-+#define LUA_INTFRMLEN "ll"
-+#define LUA_INTFRM_T long long
-+
-+#else
-+
-+#define LUA_INTFRMLEN "l"
-+#define LUA_INTFRM_T long
-+
-+#endif
-+
-+/* =================================================================== */
-+
-+/*
-+** Local configuration. You can use this space to add your redefinitions
-+** without modifying the main part of the file.
-+*/
-+
-+
-+
-+#endif
-+
---- /dev/null
-+++ b/extensions/LUA/lua/lua.h
-@@ -0,0 +1,387 @@
-+/*
-+** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $
-+** Lua - An Extensible Extension Language
-+** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
-+** See Copyright Notice at the end of this file
-+*/
-+
-+
-+#ifndef lua_h
-+#define lua_h
-+
-+#include
-+#include
-+
-+#include "luaconf.h"
-+
-+
-+#define LUA_VERSION "Lua 5.1"
-+#define LUA_RELEASE "Lua 5.1.4"
-+#define LUA_VERSION_NUM 501
-+#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
-+#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
-+
-+
-+/* mark for precompiled code (`Lua') */
-+#define LUA_SIGNATURE "\033Lua"
-+
-+/* option for multiple returns in `lua_pcall' and `lua_call' */
-+#define LUA_MULTRET (-1)
-+
-+
-+/*
-+** pseudo-indices
-+*/
-+#define LUA_REGISTRYINDEX (-10000)
-+#define LUA_ENVIRONINDEX (-10001)
-+#define LUA_GLOBALSINDEX (-10002)
-+#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
-+
-+
-+/* thread status; 0 is OK */
-+#define LUA_YIELD 1
-+#define LUA_ERRRUN 2
-+#define LUA_ERRSYNTAX 3
-+#define LUA_ERRMEM 4
-+#define LUA_ERRERR 5
-+
-+
-+typedef struct lua_State lua_State;
-+
-+typedef int (*lua_CFunction) (lua_State *L);
-+
-+
-+/*
-+** functions that read/write blocks when loading/dumping Lua chunks
-+*/
-+typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
-+
-+typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
-+
-+
-+/*
-+** prototype for memory-allocation functions
-+*/
-+typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
-+
-+
-+/*
-+** basic types
-+*/
-+#define LUA_TNONE (-1)
-+
-+#define LUA_TNIL 0
-+#define LUA_TBOOLEAN 1
-+#define LUA_TLIGHTUSERDATA 2
-+#define LUA_TNUMBER 3
-+#define LUA_TSTRING 4
-+#define LUA_TTABLE 5
-+#define LUA_TFUNCTION 6
-+#define LUA_TUSERDATA 7
-+#define LUA_TTHREAD 8
-+
-+
-+
-+/* minimum Lua stack available to a C function */
-+#define LUA_MINSTACK 20
-+
-+
-+/*
-+** generic extra include file
-+*/
-+#if defined(LUA_USER_H)
-+#include LUA_USER_H
-+#endif
-+
-+
-+/* type of numbers in Lua */
-+typedef LUA_NUMBER lua_Number;
-+
-+
-+/* type for integer functions */
-+typedef LUA_INTEGER lua_Integer;
-+
-+
-+
-+/*
-+** state manipulation
-+*/
-+LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
-+LUA_API void (lua_close) (lua_State *L);
-+LUA_API lua_State *(lua_newthread) (lua_State *L);
-+
-+LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
-+
-+
-+/*
-+** basic stack manipulation
-+*/
-+LUA_API int (lua_gettop) (lua_State *L);
-+LUA_API void (lua_settop) (lua_State *L, int idx);
-+LUA_API void (lua_pushvalue) (lua_State *L, int idx);
-+LUA_API void (lua_remove) (lua_State *L, int idx);
-+LUA_API void (lua_insert) (lua_State *L, int idx);
-+LUA_API void (lua_replace) (lua_State *L, int idx);
-+LUA_API int (lua_checkstack) (lua_State *L, int sz);
-+
-+LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
-+
-+
-+/*
-+** access functions (stack -> C)
-+*/
-+
-+LUA_API int (lua_isnumber) (lua_State *L, int idx);
-+LUA_API int (lua_isstring) (lua_State *L, int idx);
-+LUA_API int (lua_iscfunction) (lua_State *L, int idx);
-+LUA_API int (lua_isuserdata) (lua_State *L, int idx);
-+LUA_API int (lua_type) (lua_State *L, int idx);
-+LUA_API const char *(lua_typename) (lua_State *L, int tp);
-+
-+LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
-+LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
-+LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
-+
-+LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
-+LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
-+LUA_API int (lua_toboolean) (lua_State *L, int idx);
-+LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
-+LUA_API size_t (lua_objlen) (lua_State *L, int idx);
-+LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
-+LUA_API void *(lua_touserdata) (lua_State *L, int idx);
-+LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
-+LUA_API const void *(lua_topointer) (lua_State *L, int idx);
-+
-+
-+/*
-+** push functions (C -> stack)
-+*/
-+LUA_API void (lua_pushnil) (lua_State *L);
-+LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
-+LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
-+LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
-+LUA_API void (lua_pushstring) (lua_State *L, const char *s);
-+LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
-+ va_list argp);
-+LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
-+LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
-+LUA_API void (lua_pushboolean) (lua_State *L, int b);
-+LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
-+LUA_API int (lua_pushthread) (lua_State *L);
-+
-+
-+/*
-+** get functions (Lua -> stack)
-+*/
-+LUA_API void (lua_gettable) (lua_State *L, int idx);
-+LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
-+LUA_API void (lua_rawget) (lua_State *L, int idx);
-+LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
-+LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
-+LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
-+LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
-+LUA_API void (lua_getfenv) (lua_State *L, int idx);
-+
-+
-+/*
-+** set functions (stack -> Lua)
-+*/
-+LUA_API void (lua_settable) (lua_State *L, int idx);
-+LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
-+LUA_API void (lua_rawset) (lua_State *L, int idx);
-+LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
-+LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
-+LUA_API int (lua_setfenv) (lua_State *L, int idx);
-+
-+
-+/*
-+** `load' and `call' functions (load and run Lua code)
-+*/
-+LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
-+LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
-+LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
-+LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
-+ const char *chunkname);
-+
-+LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
-+
-+
-+/*
-+** coroutine functions
-+*/
-+LUA_API int (lua_yield) (lua_State *L, int nresults);
-+LUA_API int (lua_resume) (lua_State *L, int narg);
-+LUA_API int (lua_status) (lua_State *L);
-+
-+/*
-+** garbage-collection function and options
-+*/
-+
-+#define LUA_GCSTOP 0
-+#define LUA_GCRESTART 1
-+#define LUA_GCCOLLECT 2
-+#define LUA_GCCOUNT 3
-+#define LUA_GCCOUNTB 4
-+#define LUA_GCSTEP 5
-+#define LUA_GCSETPAUSE 6
-+#define LUA_GCSETSTEPMUL 7
-+
-+LUA_API int (lua_gc) (lua_State *L, int what, int data);
-+
-+
-+/*
-+** miscellaneous functions
-+*/
-+
-+LUA_API int (lua_error) (lua_State *L);
-+
-+LUA_API int (lua_next) (lua_State *L, int idx);
-+
-+LUA_API void (lua_concat) (lua_State *L, int n);
-+
-+LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
-+LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
-+
-+
-+
-+/*
-+** ===============================================================
-+** some useful macros
-+** ===============================================================
-+*/
-+
-+#define lua_pop(L,n) lua_settop(L, -(n)-1)
-+
-+#define lua_newtable(L) lua_createtable(L, 0, 0)
-+
-+#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
-+
-+#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
-+
-+#define lua_strlen(L,i) lua_objlen(L, (i))
-+
-+#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
-+#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
-+#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
-+#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
-+#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
-+#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
-+#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
-+#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
-+
-+#define lua_pushliteral(L, s) \
-+ lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
-+
-+#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
-+#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
-+
-+#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
-+
-+
-+
-+/*
-+** compatibility macros and functions
-+*/
-+
-+#define lua_open() luaL_newstate()
-+
-+#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
-+
-+#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
-+
-+#define lua_Chunkreader lua_Reader
-+#define lua_Chunkwriter lua_Writer
-+
-+
-+/* hack */
-+LUA_API void lua_setlevel (lua_State *from, lua_State *to);
-+
-+
-+/*
-+** {======================================================================
-+** Debug API
-+** =======================================================================
-+*/
-+
-+
-+/*
-+** Event codes
-+*/
-+#define LUA_HOOKCALL 0
-+#define LUA_HOOKRET 1
-+#define LUA_HOOKLINE 2
-+#define LUA_HOOKCOUNT 3
-+#define LUA_HOOKTAILRET 4
-+
-+
-+/*
-+** Event masks
-+*/
-+#define LUA_MASKCALL (1 << LUA_HOOKCALL)
-+#define LUA_MASKRET (1 << LUA_HOOKRET)
-+#define LUA_MASKLINE (1 << LUA_HOOKLINE)
-+#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
-+
-+typedef struct lua_Debug lua_Debug; /* activation record */
-+
-+
-+/* Functions to be called by the debuger in specific events */
-+typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
-+
-+
-+LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
-+LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
-+LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
-+LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
-+LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
-+LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
-+
-+LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
-+LUA_API lua_Hook lua_gethook (lua_State *L);
-+LUA_API int lua_gethookmask (lua_State *L);
-+LUA_API int lua_gethookcount (lua_State *L);
-+
-+
-+struct lua_Debug {
-+ int event;
-+ const char *name; /* (n) */
-+ const char *namewhat; /* (n) `global', `local', `field', `method' */
-+ const char *what; /* (S) `Lua', `C', `main', `tail' */
-+ const char *source; /* (S) */
-+ int currentline; /* (l) */
-+ int nups; /* (u) number of upvalues */
-+ int linedefined; /* (S) */
-+ int lastlinedefined; /* (S) */
-+ char short_src[LUA_IDSIZE]; /* (S) */
-+ /* private part */
-+ int i_ci; /* active function */
-+};
-+
-+/* }====================================================================== */
-+
-+
-+/******************************************************************************
-+* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
-+*
-+* Permission is hereby granted, free of charge, to any person obtaining
-+* a copy of this software and associated documentation files (the
-+* "Software"), to deal in the Software without restriction, including
-+* without limitation the rights to use, copy, modify, merge, publish,
-+* distribute, sublicense, and/or sell copies of the Software, and to
-+* permit persons to whom the Software is furnished to do so, subject to
-+* the following conditions:
-+*
-+* The above copyright notice and this permission notice shall be
-+* included in all copies or substantial portions of the Software.
-+*
-+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-+* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-+* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-+* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-+******************************************************************************/
-+
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/lua/lualib.h
-@@ -0,0 +1,55 @@
-+/*
-+** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $
-+** Lua standard libraries
-+** See Copyright Notice in lua.h
-+*/
-+
-+
-+#ifndef lualib_h
-+#define lualib_h
-+
-+#include "lua.h"
-+
-+
-+/* Key to file-handle type */
-+#define LUA_FILEHANDLE "FILE*"
-+
-+
-+#define LUA_COLIBNAME "coroutine"
-+LUALIB_API int (luaopen_base) (lua_State *L);
-+
-+#define LUA_TABLIBNAME "table"
-+LUALIB_API int (luaopen_table) (lua_State *L);
-+/*
-+#define LUA_IOLIBNAME "io"
-+LUALIB_API int (luaopen_io) (lua_State *L);
-+
-+#define LUA_OSLIBNAME "os"
-+LUALIB_API int (luaopen_os) (lua_State *L);
-+*/
-+
-+#define LUA_STRLIBNAME "string"
-+LUALIB_API int (luaopen_string) (lua_State *L);
-+
-+/*
-+#define LUA_MATHLIBNAME "math"
-+LUALIB_API int (luaopen_math) (lua_State *L);
-+
-+#define LUA_DBLIBNAME "debug"
-+LUALIB_API int (luaopen_debug) (lua_State *L);
-+
-+#define LUA_LOADLIBNAME "package"
-+LUALIB_API int (luaopen_package) (lua_State *L);
-+*/
-+
-+/* open all previous libraries */
-+LUALIB_API void (luaL_openlibs) (lua_State *L);
-+
-+
-+
-+#ifndef lua_assert
-+#define lua_assert(x) ((void)0)
-+#endif
-+
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/lua/lundump.c
-@@ -0,0 +1,227 @@
-+/*
-+** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
-+** load precompiled Lua chunks
-+** See Copyright Notice in lua.h
-+*/
-+
-+#include
-+
-+#define lundump_c
-+#define LUA_CORE
-+
-+#include "lua.h"
-+
-+#include "ldebug.h"
-+#include "ldo.h"
-+#include "lfunc.h"
-+#include "lmem.h"
-+#include "lobject.h"
-+#include "lstring.h"
-+#include "lundump.h"
-+#include "lzio.h"
-+
-+typedef struct {
-+ lua_State* L;
-+ ZIO* Z;
-+ Mbuffer* b;
-+ const char* name;
-+} LoadState;
-+
-+#ifdef LUAC_TRUST_BINARIES
-+#define IF(c,s)
-+#define error(S,s)
-+#else
-+#define IF(c,s) if (c) error(S,s)
-+
-+static void error(LoadState* S, const char* why)
-+{
-+ luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
-+ luaD_throw(S->L,LUA_ERRSYNTAX);
-+}
-+#endif
-+
-+#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
-+#define LoadByte(S) (lu_byte)LoadChar(S)
-+#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
-+#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
-+
-+static void LoadBlock(LoadState* S, void* b, size_t size)
-+{
-+ size_t r=luaZ_read(S->Z,b,size);
-+ IF (r!=0, "unexpected end");
-+}
-+
-+static int LoadChar(LoadState* S)
-+{
-+ char x;
-+ LoadVar(S,x);
-+ return x;
-+}
-+
-+static int LoadInt(LoadState* S)
-+{
-+ int x;
-+ LoadVar(S,x);
-+ IF (x<0, "bad integer");
-+ return x;
-+}
-+
-+static lua_Number LoadNumber(LoadState* S)
-+{
-+ lua_Number x;
-+ LoadVar(S,x);
-+ return x;
-+}
-+
-+static TString* LoadString(LoadState* S)
-+{
-+ size_t size;
-+ LoadVar(S,size);
-+ if (size==0)
-+ return NULL;
-+ else
-+ {
-+ char* s=luaZ_openspace(S->L,S->b,size);
-+ LoadBlock(S,s,size);
-+ return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
-+ }
-+}
-+
-+static void LoadCode(LoadState* S, Proto* f)
-+{
-+ int n=LoadInt(S);
-+ f->code=luaM_newvector(S->L,n,Instruction);
-+ f->sizecode=n;
-+ LoadVector(S,f->code,n,sizeof(Instruction));
-+}
-+
-+static Proto* LoadFunction(LoadState* S, TString* p);
-+
-+static void LoadConstants(LoadState* S, Proto* f)
-+{
-+ int i,n;
-+ n=LoadInt(S);
-+ f->k=luaM_newvector(S->L,n,TValue);
-+ f->sizek=n;
-+ for (i=0; ik[i]);
-+ for (i=0; ik[i];
-+ int t=LoadChar(S);
-+ switch (t)
-+ {
-+ case LUA_TNIL:
-+ setnilvalue(o);
-+ break;
-+ case LUA_TBOOLEAN:
-+ setbvalue(o,LoadChar(S)!=0);
-+ break;
-+ case LUA_TNUMBER:
-+ setnvalue(o,LoadNumber(S));
-+ break;
-+ case LUA_TSTRING:
-+ setsvalue2n(S->L,o,LoadString(S));
-+ break;
-+ default:
-+ error(S,"bad constant");
-+ break;
-+ }
-+ }
-+ n=LoadInt(S);
-+ f->p=luaM_newvector(S->L,n,Proto*);
-+ f->sizep=n;
-+ for (i=0; ip[i]=NULL;
-+ for (i=0; ip[i]=LoadFunction(S,f->source);
-+}
-+
-+static void LoadDebug(LoadState* S, Proto* f)
-+{
-+ int i,n;
-+ n=LoadInt(S);
-+ f->lineinfo=luaM_newvector(S->L,n,int);
-+ f->sizelineinfo=n;
-+ LoadVector(S,f->lineinfo,n,sizeof(int));
-+ n=LoadInt(S);
-+ f->locvars=luaM_newvector(S->L,n,LocVar);
-+ f->sizelocvars=n;
-+ for (i=0; ilocvars[i].varname=NULL;
-+ for (i=0; ilocvars[i].varname=LoadString(S);
-+ f->locvars[i].startpc=LoadInt(S);
-+ f->locvars[i].endpc=LoadInt(S);
-+ }
-+ n=LoadInt(S);
-+ f->upvalues=luaM_newvector(S->L,n,TString*);
-+ f->sizeupvalues=n;
-+ for (i=0; iupvalues[i]=NULL;
-+ for (i=0; iupvalues[i]=LoadString(S);
-+}
-+
-+static Proto* LoadFunction(LoadState* S, TString* p)
-+{
-+ Proto* f;
-+ if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
-+ f=luaF_newproto(S->L);
-+ setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
-+ f->source=LoadString(S); if (f->source==NULL) f->source=p;
-+ f->linedefined=LoadInt(S);
-+ f->lastlinedefined=LoadInt(S);
-+ f->nups=LoadByte(S);
-+ f->numparams=LoadByte(S);
-+ f->is_vararg=LoadByte(S);
-+ f->maxstacksize=LoadByte(S);
-+ LoadCode(S,f);
-+ LoadConstants(S,f);
-+ LoadDebug(S,f);
-+ IF (!luaG_checkcode(f), "bad code");
-+ S->L->top--;
-+ S->L->nCcalls--;
-+ return f;
-+}
-+
-+static void LoadHeader(LoadState* S)
-+{
-+ char h[LUAC_HEADERSIZE];
-+ char s[LUAC_HEADERSIZE];
-+ luaU_header(h);
-+ LoadBlock(S,s,LUAC_HEADERSIZE);
-+ IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
-+}
-+
-+/*
-+** load precompiled chunk
-+*/
-+Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
-+{
-+ LoadState S;
-+ if (*name=='@' || *name=='=')
-+ S.name=name+1;
-+ else if (*name==LUA_SIGNATURE[0])
-+ S.name="binary string";
-+ else
-+ S.name=name;
-+ S.L=L;
-+ S.Z=Z;
-+ S.b=buff;
-+ LoadHeader(&S);
-+ return LoadFunction(&S,luaS_newliteral(L,"=?"));
-+}
-+
-+/*
-+* make header
-+*/
-+void luaU_header (char* h)
-+{
-+ int x=1;
-+ memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
-+ h+=sizeof(LUA_SIGNATURE)-1;
-+ *h++=(char)LUAC_VERSION;
-+ *h++=(char)LUAC_FORMAT;
-+ *h++=(char)*(char*)&x; /* endianness */
-+ *h++=(char)sizeof(int);
-+ *h++=(char)sizeof(size_t);
-+ *h++=(char)sizeof(Instruction);
-+ *h++=(char)sizeof(lua_Number);
-+ *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
-+}
---- /dev/null
-+++ b/extensions/LUA/lua/lundump.h
-@@ -0,0 +1,36 @@
-+/*
-+** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
-+** load precompiled Lua chunks
-+** See Copyright Notice in lua.h
-+*/
-+
-+#ifndef lundump_h
-+#define lundump_h
-+
-+#include "lobject.h"
-+#include "lzio.h"
-+
-+/* load one chunk; from lundump.c */
-+LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
-+
-+/* make header; from lundump.c */
-+LUAI_FUNC void luaU_header (char* h);
-+
-+/* dump one chunk; from ldump.c */
-+LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
-+
-+#ifdef luac_c
-+/* print one chunk; from print.c */
-+LUAI_FUNC void luaU_print (const Proto* f, int full);
-+#endif
-+
-+/* for header of binary files -- this is Lua 5.1 */
-+#define LUAC_VERSION 0x51
-+
-+/* for header of binary files -- this is the official format */
-+#define LUAC_FORMAT 0
-+
-+/* size of header of binary files */
-+#define LUAC_HEADERSIZE 12
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/lua/lvm.c
-@@ -0,0 +1,762 @@
-+/*
-+** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $
-+** Lua virtual machine
-+** See Copyright Notice in lua.h
-+*/
-+
-+#include
-+#include
-+#include
-+
-+#define lvm_c
-+#define LUA_CORE
-+
-+#include "lua.h"
-+
-+#include "ldebug.h"
-+#include "ldo.h"
-+#include "lfunc.h"
-+#include "lgc.h"
-+#include "lobject.h"
-+#include "lopcodes.h"
-+#include "lstate.h"
-+#include "lstring.h"
-+#include "ltable.h"
-+#include "ltm.h"
-+#include "lvm.h"
-+
-+
-+
-+/* limit for table tag-method chains (to avoid loops) */
-+#define MAXTAGLOOP 100
-+
-+
-+const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
-+ lua_Number num;
-+ if (ttisnumber(obj)) return obj;
-+ if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
-+ setnvalue(n, num);
-+ return n;
-+ }
-+ else
-+ return NULL;
-+}
-+
-+
-+int luaV_tostring (lua_State *L, StkId obj) {
-+ if (!ttisnumber(obj))
-+ return 0;
-+ else {
-+ char s[LUAI_MAXNUMBER2STR];
-+ lua_Number n = nvalue(obj);
-+ lua_number2str(s, n);
-+ setsvalue2s(L, obj, luaS_new(L, s));
-+ return 1;
-+ }
-+}
-+
-+
-+static void traceexec (lua_State *L, const Instruction *pc) {
-+ lu_byte mask = L->hookmask;
-+ const Instruction *oldpc = L->savedpc;
-+ L->savedpc = pc;
-+ if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
-+ resethookcount(L);
-+ luaD_callhook(L, LUA_HOOKCOUNT, -1);
-+ }
-+ if (mask & LUA_MASKLINE) {
-+ Proto *p = ci_func(L->ci)->l.p;
-+ int npc = pcRel(pc, p);
-+ int newline = getline(p, npc);
-+ /* call linehook when enter a new function, when jump back (loop),
-+ or when enter a new line */
-+ if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
-+ luaD_callhook(L, LUA_HOOKLINE, newline);
-+ }
-+}
-+
-+
-+static void callTMres (lua_State *L, StkId res, const TValue *f,
-+ const TValue *p1, const TValue *p2) {
-+ ptrdiff_t result = savestack(L, res);
-+ setobj2s(L, L->top, f); /* push function */
-+ setobj2s(L, L->top+1, p1); /* 1st argument */
-+ setobj2s(L, L->top+2, p2); /* 2nd argument */
-+ luaD_checkstack(L, 3);
-+ L->top += 3;
-+ luaD_call(L, L->top - 3, 1);
-+ res = restorestack(L, result);
-+ L->top--;
-+ setobjs2s(L, res, L->top);
-+}
-+
-+
-+
-+static void callTM (lua_State *L, const TValue *f, const TValue *p1,
-+ const TValue *p2, const TValue *p3) {
-+ setobj2s(L, L->top, f); /* push function */
-+ setobj2s(L, L->top+1, p1); /* 1st argument */
-+ setobj2s(L, L->top+2, p2); /* 2nd argument */
-+ setobj2s(L, L->top+3, p3); /* 3th argument */
-+ luaD_checkstack(L, 4);
-+ L->top += 4;
-+ luaD_call(L, L->top - 4, 0);
-+}
-+
-+
-+void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
-+ int loop;
-+ for (loop = 0; loop < MAXTAGLOOP; loop++) {
-+ const TValue *tm;
-+ if (ttistable(t)) { /* `t' is a table? */
-+ Table *h = hvalue(t);
-+ const TValue *res = luaH_get(h, key); /* do a primitive get */
-+ if (!ttisnil(res) || /* result is no nil? */
-+ (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
-+ setobj2s(L, val, res);
-+ return;
-+ }
-+ /* else will try the tag method */
-+ }
-+ else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
-+ luaG_typeerror(L, t, "index");
-+ if (ttisfunction(tm)) {
-+ callTMres(L, val, tm, t, key);
-+ return;
-+ }
-+ t = tm; /* else repeat with `tm' */
-+ }
-+ luaG_runerror(L, "loop in gettable");
-+}
-+
-+
-+void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
-+ int loop;
-+ for (loop = 0; loop < MAXTAGLOOP; loop++) {
-+ const TValue *tm;
-+ if (ttistable(t)) { /* `t' is a table? */
-+ Table *h = hvalue(t);
-+ TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
-+ if (!ttisnil(oldval) || /* result is no nil? */
-+ (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
-+ setobj2t(L, oldval, val);
-+ luaC_barriert(L, h, val);
-+ return;
-+ }
-+ /* else will try the tag method */
-+ }
-+ else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
-+ luaG_typeerror(L, t, "index");
-+ if (ttisfunction(tm)) {
-+ callTM(L, tm, t, key, val);
-+ return;
-+ }
-+ t = tm; /* else repeat with `tm' */
-+ }
-+ luaG_runerror(L, "loop in settable");
-+}
-+
-+
-+static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
-+ StkId res, TMS event) {
-+ const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
-+ if (ttisnil(tm))
-+ tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
-+ if (ttisnil(tm)) return 0;
-+ callTMres(L, res, tm, p1, p2);
-+ return 1;
-+}
-+
-+
-+static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
-+ TMS event) {
-+ const TValue *tm1 = fasttm(L, mt1, event);
-+ const TValue *tm2;
-+ if (tm1 == NULL) return NULL; /* no metamethod */
-+ if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
-+ tm2 = fasttm(L, mt2, event);
-+ if (tm2 == NULL) return NULL; /* no metamethod */
-+ if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
-+ return tm1;
-+ return NULL;
-+}
-+
-+
-+static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
-+ TMS event) {
-+ const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
-+ const TValue *tm2;
-+ if (ttisnil(tm1)) return -1; /* no metamethod? */
-+ tm2 = luaT_gettmbyobj(L, p2, event);
-+ if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
-+ return -1;
-+ callTMres(L, L->top, tm1, p1, p2);
-+ return !l_isfalse(L->top);
-+}
-+
-+
-+static int l_strcmp (const TString *ls, const TString *rs) {
-+ const char *l = getstr(ls);
-+ size_t ll = ls->tsv.len;
-+ const char *r = getstr(rs);
-+ size_t lr = rs->tsv.len;
-+ for (;;) {
-+ int temp = strcoll(l, r);
-+ if (temp != 0) return temp;
-+ else { /* strings are equal up to a `\0' */
-+ size_t len = strlen(l); /* index of first `\0' in both strings */
-+ if (len == lr) /* r is finished? */
-+ return (len == ll) ? 0 : 1;
-+ else if (len == ll) /* l is finished? */
-+ return -1; /* l is smaller than r (because r is not finished) */
-+ /* both strings longer than `len'; go on comparing (after the `\0') */
-+ len++;
-+ l += len; ll -= len; r += len; lr -= len;
-+ }
-+ }
-+}
-+
-+
-+int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
-+ int res;
-+ if (ttype(l) != ttype(r))
-+ return luaG_ordererror(L, l, r);
-+ else if (ttisnumber(l))
-+ return luai_numlt(nvalue(l), nvalue(r));
-+ else if (ttisstring(l))
-+ return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
-+ else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
-+ return res;
-+ return luaG_ordererror(L, l, r);
-+}
-+
-+
-+static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
-+ int res;
-+ if (ttype(l) != ttype(r))
-+ return luaG_ordererror(L, l, r);
-+ else if (ttisnumber(l))
-+ return luai_numle(nvalue(l), nvalue(r));
-+ else if (ttisstring(l))
-+ return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
-+ else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
-+ return res;
-+ else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
-+ return !res;
-+ return luaG_ordererror(L, l, r);
-+}
-+
-+
-+int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
-+ const TValue *tm;
-+ lua_assert(ttype(t1) == ttype(t2));
-+ switch (ttype(t1)) {
-+ case LUA_TNIL: return 1;
-+ case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
-+ case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
-+ case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
-+ case LUA_TUSERDATA: {
-+ if (uvalue(t1) == uvalue(t2)) return 1;
-+ tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
-+ TM_EQ);
-+ break; /* will try TM */
-+ }
-+ case LUA_TTABLE: {
-+ if (hvalue(t1) == hvalue(t2)) return 1;
-+ tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
-+ break; /* will try TM */
-+ }
-+ default: return gcvalue(t1) == gcvalue(t2);
-+ }
-+ if (tm == NULL) return 0; /* no TM? */
-+ callTMres(L, L->top, tm, t1, t2); /* call TM */
-+ return !l_isfalse(L->top);
-+}
-+
-+
-+void luaV_concat (lua_State *L, int total, int last) {
-+ do {
-+ StkId top = L->base + last + 1;
-+ int n = 2; /* number of elements handled in this pass (at least 2) */
-+ if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
-+ if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
-+ luaG_concaterror(L, top-2, top-1);
-+ } else if (tsvalue(top-1)->len == 0) /* second op is empty? */
-+ (void)tostring(L, top - 2); /* result is first op (as string) */
-+ else {
-+ /* at least two string values; get as many as possible */
-+ size_t tl = tsvalue(top-1)->len;
-+ char *buffer;
-+ int i;
-+ /* collect total length */
-+ for (n = 1; n < total && tostring(L, top-n-1); n++) {
-+ size_t l = tsvalue(top-n-1)->len;
-+ if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
-+ tl += l;
-+ }
-+ buffer = luaZ_openspace(L, &G(L)->buff, tl);
-+ tl = 0;
-+ for (i=n; i>0; i--) { /* concat all strings */
-+ size_t l = tsvalue(top-i)->len;
-+ memcpy(buffer+tl, svalue(top-i), l);
-+ tl += l;
-+ }
-+ setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
-+ }
-+ total -= n-1; /* got `n' strings to create 1 new */
-+ last -= n-1;
-+ } while (total > 1); /* repeat until only 1 result left */
-+}
-+
-+
-+static void Arith (lua_State *L, StkId ra, const TValue *rb,
-+ const TValue *rc, TMS op) {
-+ TValue tempb, tempc;
-+ const TValue *b, *c;
-+ if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
-+ (c = luaV_tonumber(rc, &tempc)) != NULL) {
-+ lua_Number nb = nvalue(b), nc = nvalue(c);
-+ switch (op) {
-+ case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
-+ case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
-+ case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
-+ case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
-+ case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
-+ case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
-+ case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
-+ default: lua_assert(0); break;
-+ }
-+ }
-+ else if (!call_binTM(L, rb, rc, ra, op))
-+ luaG_aritherror(L, rb, rc);
-+}
-+
-+
-+
-+/*
-+** some macros for common tasks in `luaV_execute'
-+*/
-+
-+#define runtime_check(L, c) { if (!(c)) break; }
-+
-+#define RA(i) (base+GETARG_A(i))
-+/* to be used after possible stack reallocation */
-+#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
-+#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
-+#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
-+ ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
-+#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
-+ ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
-+#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
-+
-+
-+#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);}
-+
-+
-+#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
-+
-+
-+#define arith_op(op,tm) { \
-+ TValue *rb = RKB(i); \
-+ TValue *rc = RKC(i); \
-+ if (ttisnumber(rb) && ttisnumber(rc)) { \
-+ lua_Number nb = nvalue(rb), nc = nvalue(rc); \
-+ setnvalue(ra, op(nb, nc)); \
-+ } \
-+ else \
-+ Protect(Arith(L, ra, rb, rc, tm)); \
-+ }
-+
-+
-+
-+void luaV_execute (lua_State *L, int nexeccalls) {
-+ LClosure *cl;
-+ StkId base;
-+ TValue *k;
-+ const Instruction *pc;
-+ reentry: /* entry point */
-+ lua_assert(isLua(L->ci));
-+ pc = L->savedpc;
-+ cl = &clvalue(L->ci->func)->l;
-+ base = L->base;
-+ k = cl->p->k;
-+ /* main loop of interpreter */
-+ for (;;) {
-+ const Instruction i = *pc++;
-+ StkId ra;
-+ if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
-+ (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
-+ traceexec(L, pc);
-+ if (L->status == LUA_YIELD) { /* did hook yield? */
-+ L->savedpc = pc - 1;
-+ return;
-+ }
-+ base = L->base;
-+ }
-+ /* warning!! several calls may realloc the stack and invalidate `ra' */
-+ ra = RA(i);
-+ lua_assert(base == L->base && L->base == L->ci->base);
-+ lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
-+ lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
-+ switch (GET_OPCODE(i)) {
-+ case OP_MOVE: {
-+ setobjs2s(L, ra, RB(i));
-+ continue;
-+ }
-+ case OP_LOADK: {
-+ setobj2s(L, ra, KBx(i));
-+ continue;
-+ }
-+ case OP_LOADBOOL: {
-+ setbvalue(ra, GETARG_B(i));
-+ if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
-+ continue;
-+ }
-+ case OP_LOADNIL: {
-+ TValue *rb = RB(i);
-+ do {
-+ setnilvalue(rb--);
-+ } while (rb >= ra);
-+ continue;
-+ }
-+ case OP_GETUPVAL: {
-+ int b = GETARG_B(i);
-+ setobj2s(L, ra, cl->upvals[b]->v);
-+ continue;
-+ }
-+ case OP_GETGLOBAL: {
-+ TValue g;
-+ TValue *rb = KBx(i);
-+ sethvalue(L, &g, cl->env);
-+ lua_assert(ttisstring(rb));
-+ Protect(luaV_gettable(L, &g, rb, ra));
-+ continue;
-+ }
-+ case OP_GETTABLE: {
-+ Protect(luaV_gettable(L, RB(i), RKC(i), ra));
-+ continue;
-+ }
-+ case OP_SETGLOBAL: {
-+ TValue g;
-+ sethvalue(L, &g, cl->env);
-+ lua_assert(ttisstring(KBx(i)));
-+ Protect(luaV_settable(L, &g, KBx(i), ra));
-+ continue;
-+ }
-+ case OP_SETUPVAL: {
-+ UpVal *uv = cl->upvals[GETARG_B(i)];
-+ setobj(L, uv->v, ra);
-+ luaC_barrier(L, uv, ra);
-+ continue;
-+ }
-+ case OP_SETTABLE: {
-+ Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
-+ continue;
-+ }
-+ case OP_NEWTABLE: {
-+ int b = GETARG_B(i);
-+ int c = GETARG_C(i);
-+ sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
-+ Protect(luaC_checkGC(L));
-+ continue;
-+ }
-+ case OP_SELF: {
-+ StkId rb = RB(i);
-+ setobjs2s(L, ra+1, rb);
-+ Protect(luaV_gettable(L, rb, RKC(i), ra));
-+ continue;
-+ }
-+ case OP_ADD: {
-+ arith_op(luai_numadd, TM_ADD);
-+ continue;
-+ }
-+ case OP_SUB: {
-+ arith_op(luai_numsub, TM_SUB);
-+ continue;
-+ }
-+ case OP_MUL: {
-+ arith_op(luai_nummul, TM_MUL);
-+ continue;
-+ }
-+ case OP_DIV: {
-+ arith_op(luai_numdiv, TM_DIV);
-+ continue;
-+ }
-+ case OP_MOD: {
-+ arith_op(luai_nummod, TM_MOD);
-+ continue;
-+ }
-+ case OP_POW: {
-+ arith_op(luai_numpow, TM_POW);
-+ continue;
-+ }
-+ case OP_UNM: {
-+ TValue *rb = RB(i);
-+ if (ttisnumber(rb)) {
-+ lua_Number nb = nvalue(rb);
-+ setnvalue(ra, luai_numunm(nb));
-+ }
-+ else {
-+ Protect(Arith(L, ra, rb, rb, TM_UNM));
-+ }
-+ continue;
-+ }
-+ case OP_NOT: {
-+ int res = l_isfalse(RB(i)); /* next assignment may change this value */
-+ setbvalue(ra, res);
-+ continue;
-+ }
-+ case OP_LEN: {
-+ const TValue *rb = RB(i);
-+ switch (ttype(rb)) {
-+ case LUA_TTABLE: {
-+ setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
-+ break;
-+ }
-+ case LUA_TSTRING: {
-+ setnvalue(ra, cast_num(tsvalue(rb)->len));
-+ break;
-+ }
-+ default: { /* try metamethod */
-+ Protect(
-+ if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
-+ luaG_typeerror(L, rb, "get length of");
-+ )
-+ }
-+ }
-+ continue;
-+ }
-+ case OP_CONCAT: {
-+ int b = GETARG_B(i);
-+ int c = GETARG_C(i);
-+ Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
-+ setobjs2s(L, RA(i), base+b);
-+ continue;
-+ }
-+ case OP_JMP: {
-+ dojump(L, pc, GETARG_sBx(i));
-+ continue;
-+ }
-+ case OP_EQ: {
-+ TValue *rb = RKB(i);
-+ TValue *rc = RKC(i);
-+ Protect(
-+ if (equalobj(L, rb, rc) == GETARG_A(i))
-+ dojump(L, pc, GETARG_sBx(*pc));
-+ )
-+ pc++;
-+ continue;
-+ }
-+ case OP_LT: {
-+ Protect(
-+ if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
-+ dojump(L, pc, GETARG_sBx(*pc));
-+ )
-+ pc++;
-+ continue;
-+ }
-+ case OP_LE: {
-+ Protect(
-+ if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
-+ dojump(L, pc, GETARG_sBx(*pc));
-+ )
-+ pc++;
-+ continue;
-+ }
-+ case OP_TEST: {
-+ if (l_isfalse(ra) != GETARG_C(i))
-+ dojump(L, pc, GETARG_sBx(*pc));
-+ pc++;
-+ continue;
-+ }
-+ case OP_TESTSET: {
-+ TValue *rb = RB(i);
-+ if (l_isfalse(rb) != GETARG_C(i)) {
-+ setobjs2s(L, ra, rb);
-+ dojump(L, pc, GETARG_sBx(*pc));
-+ }
-+ pc++;
-+ continue;
-+ }
-+ case OP_CALL: {
-+ int b = GETARG_B(i);
-+ int nresults = GETARG_C(i) - 1;
-+ if (b != 0) L->top = ra+b; /* else previous instruction set top */
-+ L->savedpc = pc;
-+ switch (luaD_precall(L, ra, nresults)) {
-+ case PCRLUA: {
-+ nexeccalls++;
-+ goto reentry; /* restart luaV_execute over new Lua function */
-+ }
-+ case PCRC: {
-+ /* it was a C function (`precall' called it); adjust results */
-+ if (nresults >= 0) L->top = L->ci->top;
-+ base = L->base;
-+ continue;
-+ }
-+ default: {
-+ return; /* yield */
-+ }
-+ }
-+ }
-+ case OP_TAILCALL: {
-+ int b = GETARG_B(i);
-+ if (b != 0) L->top = ra+b; /* else previous instruction set top */
-+ L->savedpc = pc;
-+ lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
-+ switch (luaD_precall(L, ra, LUA_MULTRET)) {
-+ case PCRLUA: {
-+ /* tail call: put new frame in place of previous one */
-+ CallInfo *ci = L->ci - 1; /* previous frame */
-+ int aux;
-+ StkId func = ci->func;
-+ StkId pfunc = (ci+1)->func; /* previous function index */
-+ if (L->openupval) luaF_close(L, ci->base);
-+ L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
-+ for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
-+ setobjs2s(L, func+aux, pfunc+aux);
-+ ci->top = L->top = func+aux; /* correct top */
-+ lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
-+ ci->savedpc = L->savedpc;
-+ ci->tailcalls++; /* one more call lost */
-+ L->ci--; /* remove new frame */
-+ goto reentry;
-+ }
-+ case PCRC: { /* it was a C function (`precall' called it) */
-+ base = L->base;
-+ continue;
-+ }
-+ default: {
-+ return; /* yield */
-+ }
-+ }
-+ }
-+ case OP_RETURN: {
-+ int b = GETARG_B(i);
-+ if (b != 0) L->top = ra+b-1;
-+ if (L->openupval) luaF_close(L, base);
-+ L->savedpc = pc;
-+ b = luaD_poscall(L, ra);
-+ if (--nexeccalls == 0) /* was previous function running `here'? */
-+ return; /* no: return */
-+ else { /* yes: continue its execution */
-+ if (b) L->top = L->ci->top;
-+ lua_assert(isLua(L->ci));
-+ lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
-+ goto reentry;
-+ }
-+ }
-+ case OP_FORLOOP: {
-+ lua_Number step = nvalue(ra+2);
-+ lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
-+ lua_Number limit = nvalue(ra+1);
-+ if (luai_numlt(0, step) ? luai_numle(idx, limit)
-+ : luai_numle(limit, idx)) {
-+ dojump(L, pc, GETARG_sBx(i)); /* jump back */
-+ setnvalue(ra, idx); /* update internal index... */
-+ setnvalue(ra+3, idx); /* ...and external index */
-+ }
-+ continue;
-+ }
-+ case OP_FORPREP: {
-+ const TValue *init = ra;
-+ const TValue *plimit = ra+1;
-+ const TValue *pstep = ra+2;
-+ L->savedpc = pc; /* next steps may throw errors */
-+ if (!tonumber(init, ra))
-+ luaG_runerror(L, LUA_QL("for") " initial value must be a number");
-+ else if (!tonumber(plimit, ra+1))
-+ luaG_runerror(L, LUA_QL("for") " limit must be a number");
-+ else if (!tonumber(pstep, ra+2))
-+ luaG_runerror(L, LUA_QL("for") " step must be a number");
-+ setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
-+ dojump(L, pc, GETARG_sBx(i));
-+ continue;
-+ }
-+ case OP_TFORLOOP: {
-+ StkId cb = ra + 3; /* call base */
-+ setobjs2s(L, cb+2, ra+2);
-+ setobjs2s(L, cb+1, ra+1);
-+ setobjs2s(L, cb, ra);
-+ L->top = cb+3; /* func. + 2 args (state and index) */
-+ Protect(luaD_call(L, cb, GETARG_C(i)));
-+ L->top = L->ci->top;
-+ cb = RA(i) + 3; /* previous call may change the stack */
-+ if (!ttisnil(cb)) { /* continue loop? */
-+ setobjs2s(L, cb-1, cb); /* save control variable */
-+ dojump(L, pc, GETARG_sBx(*pc)); /* jump back */
-+ }
-+ pc++;
-+ continue;
-+ }
-+ case OP_SETLIST: {
-+ int n = GETARG_B(i);
-+ int c = GETARG_C(i);
-+ int last;
-+ Table *h;
-+ if (n == 0) {
-+ n = cast_int(L->top - ra) - 1;
-+ L->top = L->ci->top;
-+ }
-+ if (c == 0) c = cast_int(*pc++);
-+ runtime_check(L, ttistable(ra));
-+ h = hvalue(ra);
-+ last = ((c-1)*LFIELDS_PER_FLUSH) + n;
-+ if (last > h->sizearray) /* needs more space? */
-+ luaH_resizearray(L, h, last); /* pre-alloc it at once */
-+ for (; n > 0; n--) {
-+ TValue *val = ra+n;
-+ setobj2t(L, luaH_setnum(L, h, last--), val);
-+ luaC_barriert(L, h, val);
-+ }
-+ continue;
-+ }
-+ case OP_CLOSE: {
-+ luaF_close(L, ra);
-+ continue;
-+ }
-+ case OP_CLOSURE: {
-+ Proto *p;
-+ Closure *ncl;
-+ int nup, j;
-+ p = cl->p->p[GETARG_Bx(i)];
-+ nup = p->nups;
-+ ncl = luaF_newLclosure(L, nup, cl->env);
-+ ncl->l.p = p;
-+ for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)];
-+ else {
-+ lua_assert(GET_OPCODE(*pc) == OP_MOVE);
-+ ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
-+ }
-+ }
-+ setclvalue(L, ra, ncl);
-+ Protect(luaC_checkGC(L));
-+ continue;
-+ }
-+ case OP_VARARG: {
-+ int b = GETARG_B(i) - 1;
-+ int j;
-+ CallInfo *ci = L->ci;
-+ int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
-+ if (b == LUA_MULTRET) {
-+ Protect(luaD_checkstack(L, n));
-+ ra = RA(i); /* previous call may change the stack */
-+ b = n;
-+ L->top = ra + n;
-+ }
-+ for (j = 0; j < b; j++) {
-+ if (j < n) {
-+ setobjs2s(L, ra + j, ci->base - n + j);
-+ }
-+ else {
-+ setnilvalue(ra + j);
-+ }
-+ }
-+ continue;
-+ }
-+ }
-+ }
-+}
-+
---- /dev/null
-+++ b/extensions/LUA/lua/lvm.h
-@@ -0,0 +1,36 @@
-+/*
-+** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $
-+** Lua virtual machine
-+** See Copyright Notice in lua.h
-+*/
-+
-+#ifndef lvm_h
-+#define lvm_h
-+
-+
-+#include "ldo.h"
-+#include "lobject.h"
-+#include "ltm.h"
-+
-+
-+#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
-+
-+#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
-+ (((o) = luaV_tonumber(o,n)) != NULL))
-+
-+#define equalobj(L,o1,o2) \
-+ (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
-+
-+
-+LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
-+LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
-+LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
-+LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
-+LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
-+ StkId val);
-+LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
-+ StkId val);
-+LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
-+LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/lua/lzio.c
-@@ -0,0 +1,81 @@
-+/*
-+** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
-+** a generic input stream interface
-+** See Copyright Notice in lua.h
-+*/
-+
-+#include
-+
-+#define lzio_c
-+#define LUA_CORE
-+
-+#include "lua.h"
-+
-+#include "llimits.h"
-+#include "lmem.h"
-+#include "lstate.h"
-+#include "lzio.h"
-+
-+
-+int luaZ_fill (ZIO *z) {
-+ size_t size;
-+ lua_State *L = z->L;
-+ const char *buff;
-+ lua_unlock(L);
-+ buff = z->reader(L, z->data, &size);
-+ lua_lock(L);
-+ if (buff == NULL || size == 0) return EOZ;
-+ z->n = size - 1;
-+ z->p = buff;
-+ return char2int(*(z->p++));
-+}
-+
-+
-+int luaZ_lookahead (ZIO *z) {
-+ if (z->n == 0) {
-+ if (luaZ_fill(z) == EOZ)
-+ return EOZ;
-+ else {
-+ z->n++; /* luaZ_fill removed first byte; put back it */
-+ z->p--;
-+ }
-+ }
-+ return char2int(*z->p);
-+}
-+
-+
-+void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
-+ z->L = L;
-+ z->reader = reader;
-+ z->data = data;
-+ z->n = 0;
-+ z->p = NULL;
-+}
-+
-+
-+/* --------------------------------------------------------------- read --- */
-+size_t luaZ_read (ZIO *z, void *b, size_t n) {
-+ while (n) {
-+ size_t m;
-+ if (luaZ_lookahead(z) == EOZ)
-+ return n; /* return number of missing bytes */
-+ m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
-+ memcpy(b, z->p, m);
-+ z->n -= m;
-+ z->p += m;
-+ b = (char *)b + m;
-+ n -= m;
-+ }
-+ return 0;
-+}
-+
-+/* ------------------------------------------------------------------------ */
-+char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
-+ if (n > buff->buffsize) {
-+ if (n < LUA_MINBUFFER) n = LUA_MINBUFFER;
-+ luaZ_resizebuffer(L, buff, n);
-+ }
-+ return buff->buffer;
-+}
-+
-+
---- /dev/null
-+++ b/extensions/LUA/lua/lzio.h
-@@ -0,0 +1,67 @@
-+/*
-+** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $
-+** Buffered streams
-+** See Copyright Notice in lua.h
-+*/
-+
-+
-+#ifndef lzio_h
-+#define lzio_h
-+
-+#include "lua.h"
-+
-+#include "lmem.h"
-+
-+
-+#define EOZ (-1) /* end of stream */
-+
-+typedef struct Zio ZIO;
-+
-+#define char2int(c) cast(int, cast(unsigned char, (c)))
-+
-+#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
-+
-+typedef struct Mbuffer {
-+ char *buffer;
-+ size_t n;
-+ size_t buffsize;
-+} Mbuffer;
-+
-+#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0)
-+
-+#define luaZ_buffer(buff) ((buff)->buffer)
-+#define luaZ_sizebuffer(buff) ((buff)->buffsize)
-+#define luaZ_bufflen(buff) ((buff)->n)
-+
-+#define luaZ_resetbuffer(buff) ((buff)->n = 0)
-+
-+
-+#define luaZ_resizebuffer(L, buff, size) \
-+ (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \
-+ (buff)->buffsize = size)
-+
-+#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)
-+
-+
-+LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
-+LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
-+ void *data);
-+LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
-+LUAI_FUNC int luaZ_lookahead (ZIO *z);
-+
-+
-+
-+/* --------- Private Part ------------------ */
-+
-+struct Zio {
-+ size_t n; /* bytes still unread */
-+ const char *p; /* current position in buffer */
-+ lua_Reader reader;
-+ void* data; /* additional data */
-+ lua_State *L; /* Lua state (for reader) */
-+};
-+
-+
-+LUAI_FUNC int luaZ_fill (ZIO *z);
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/Makefile
-@@ -0,0 +1,389 @@
-+# Makefile.in generated by automake 1.11.1 from Makefile.am.
-+# extensions/LUA/Makefile. Generated from Makefile.in by configure.
-+
-+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-+# Inc.
-+# This Makefile.in is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-+
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-+# PARTICULAR PURPOSE.
-+
-+
-+
-+# -*- Makefile -*-
-+# AUTOMAKE
-+
-+pkgdatadir = $(datadir)/xtables-addons
-+pkgincludedir = $(includedir)/xtables-addons
-+pkglibdir = $(libdir)/xtables-addons
-+pkglibexecdir = $(libexecdir)/xtables-addons
-+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-+install_sh_DATA = $(install_sh) -c -m 644
-+install_sh_PROGRAM = $(install_sh) -c
-+install_sh_SCRIPT = $(install_sh) -c
-+INSTALL_HEADER = $(INSTALL_DATA)
-+transform = $(program_transform_name)
-+NORMAL_INSTALL = :
-+PRE_INSTALL = :
-+POST_INSTALL = :
-+NORMAL_UNINSTALL = :
-+PRE_UNINSTALL = :
-+POST_UNINSTALL = :
-+build_triplet = i686-pc-linux-gnu
-+host_triplet = i686-pc-linux-gnu
-+DIST_COMMON = $(srcdir)/../../Makefile.extra $(srcdir)/Makefile.am \
-+ $(srcdir)/Makefile.in
-+subdir = extensions/LUA
-+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
-+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-+ $(top_srcdir)/configure.ac
-+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-+ $(ACLOCAL_M4)
-+mkinstalldirs = $(install_sh) -d
-+CONFIG_HEADER = $(top_builddir)/config.h
-+CONFIG_CLEAN_FILES =
-+CONFIG_CLEAN_VPATH_FILES =
-+SOURCES =
-+DIST_SOURCES =
-+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-+ACLOCAL = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run aclocal-1.11
-+AMTAR = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run tar
-+AR = ar
-+AUTOCONF = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run autoconf
-+AUTOHEADER = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run autoheader
-+AUTOMAKE = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run automake-1.11
-+AWK = mawk
-+CC = gcc
-+CCDEPMODE = depmode=gcc3
-+CFLAGS = -g -O2
-+CPP = gcc -E
-+CPPFLAGS =
-+CYGPATH_W = echo
-+DEFS = -DHAVE_CONFIG_H
-+DEPDIR = .deps
-+DSYMUTIL =
-+DUMPBIN =
-+ECHO_C =
-+ECHO_N = -n
-+ECHO_T =
-+EGREP = /bin/grep -E
-+EXEEXT =
-+FGREP = /bin/grep -F
-+GREP = /bin/grep
-+INSTALL = /usr/bin/install -c
-+INSTALL_DATA = ${INSTALL} -m 644
-+INSTALL_PROGRAM = ${INSTALL}
-+INSTALL_SCRIPT = ${INSTALL}
-+INSTALL_STRIP_PROGRAM = $(install_sh) -c -s
-+LD = /usr/bin/ld
-+LDFLAGS =
-+LIBOBJS =
-+LIBS =
-+LIBTOOL = $(SHELL) $(top_builddir)/libtool
-+LIPO =
-+LN_S = ln -s
-+LTLIBOBJS =
-+MAKEINFO = ${SHELL} /home/andre/Dropbox/xtables-addons/missing --run makeinfo
-+MKDIR_P = /bin/mkdir -p
-+NM = /usr/bin/nm -B
-+NMEDIT =
-+OBJDUMP = objdump
-+OBJEXT = o
-+OTOOL =
-+OTOOL64 =
-+PACKAGE = xtables-addons
-+PACKAGE_BUGREPORT =
-+PACKAGE_NAME = xtables-addons
-+PACKAGE_STRING = xtables-addons 1.21
-+PACKAGE_TARNAME = xtables-addons
-+PACKAGE_URL =
-+PACKAGE_VERSION = 1.21
-+PATH_SEPARATOR = :
-+PKG_CONFIG = /usr/bin/pkg-config
-+RANLIB = ranlib
-+SED = /bin/sed
-+SET_MAKE =
-+SHELL = /bin/bash
-+STRIP = strip
-+VERSION = 1.21
-+abs_builddir = /home/andre/Dropbox/xtables-addons/extensions/LUA
-+abs_srcdir = /home/andre/Dropbox/xtables-addons/extensions/LUA
-+abs_top_builddir = /home/andre/Dropbox/xtables-addons
-+abs_top_srcdir = /home/andre/Dropbox/xtables-addons
-+ac_ct_CC = gcc
-+ac_ct_DUMPBIN =
-+am__include = include
-+am__leading_dot = .
-+am__quote =
-+am__tar = ${AMTAR} chof - "$$tardir"
-+am__untar = ${AMTAR} xf -
-+bindir = ${exec_prefix}/bin
-+build = i686-pc-linux-gnu
-+build_alias =
-+build_cpu = i686
-+build_os = linux-gnu
-+build_vendor = pc
-+builddir = .
-+datadir = ${datarootdir}
-+datarootdir = ${prefix}/share
-+docdir = ${datarootdir}/doc/${PACKAGE_TARNAME}
-+dvidir = ${docdir}
-+exec_prefix = ${prefix}
-+host = i686-pc-linux-gnu
-+host_alias =
-+host_cpu = i686
-+host_os = linux-gnu
-+host_vendor = pc
-+htmldir = ${docdir}
-+includedir = ${prefix}/include
-+infodir = ${datarootdir}/info
-+install_sh = ${SHELL} /home/andre/Dropbox/xtables-addons/install-sh
-+kbuilddir = /lib/modules/2.6.33-020633-generic/build
-+kinclude_CFLAGS = -I /lib/modules/2.6.33-020633-generic/build/include
-+ksourcedir =
-+libdir = ${exec_prefix}/lib
-+libexecdir = ${exec_prefix}/libexec
-+libxtables_CFLAGS =
-+libxtables_LIBS = -L/lib -lxtables
-+localedir = ${datarootdir}/locale
-+localstatedir = ${prefix}/var
-+lt_ECHO = echo
-+mandir = ${datarootdir}/man
-+mkdir_p = /bin/mkdir -p
-+oldincludedir = /usr/include
-+pdfdir = ${docdir}
-+prefix = /usr/local
-+program_transform_name = s,x,x,
-+psdir = ${docdir}
-+regular_CFLAGS = -D_LARGEFILE_SOURCE=1 -D_LARGE_FILES -D_FILE_OFFSET_BITS=64 -D_REENTRANT -Wall -Waggregate-return -Wmissing-declarations -Wmissing-prototypes -Wredundant-decls -Wshadow -Wstrict-prototypes -Winline -pipe -DXTABLES_LIBDIR=\"${xtlibdir}\"
-+sbindir = ${exec_prefix}/sbin
-+sharedstatedir = ${prefix}/com
-+srcdir = .
-+sysconfdir = ${prefix}/etc
-+target_alias =
-+top_build_prefix = ../../
-+top_builddir = ../..
-+top_srcdir = ../..
-+xtlibdir = ${libexecdir}/xtables
-+XA_SRCDIR = ${srcdir}
-+XA_TOPSRCDIR = ${top_srcdir}
-+XA_ABSTOPSRCDIR = ${abs_top_srcdir}
-+_mcall = -f ${top_builddir}/Makefile.iptrules
-+all: all-am
-+
-+.SUFFIXES:
-+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/../../Makefile.extra $(am__configure_deps)
-+ @for dep in $?; do \
-+ case '$(am__configure_deps)' in \
-+ *$$dep*) \
-+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-+ && { if test -f $@; then exit 0; else break; fi; }; \
-+ exit 1;; \
-+ esac; \
-+ done; \
-+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/LUA/Makefile'; \
-+ $(am__cd) $(top_srcdir) && \
-+ $(AUTOMAKE) --foreign extensions/LUA/Makefile
-+.PRECIOUS: Makefile
-+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-+ @case '$?' in \
-+ *config.status*) \
-+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-+ *) \
-+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-+ esac;
-+
-+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-+
-+$(top_srcdir)/configure: $(am__configure_deps)
-+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
-+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-+$(am__aclocal_m4_deps):
-+
-+mostlyclean-libtool:
-+ -rm -f *.lo
-+
-+clean-libtool:
-+ -rm -rf .libs _libs
-+tags: TAGS
-+TAGS:
-+
-+ctags: CTAGS
-+CTAGS:
-+
-+
-+distdir: $(DISTFILES)
-+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-+ list='$(DISTFILES)'; \
-+ dist_files=`for file in $$list; do echo $$file; done | \
-+ sed -e "s|^$$srcdirstrip/||;t" \
-+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-+ case $$dist_files in \
-+ */*) $(MKDIR_P) `echo "$$dist_files" | \
-+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-+ sort -u` ;; \
-+ esac; \
-+ for file in $$dist_files; do \
-+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-+ if test -d $$d/$$file; then \
-+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-+ if test -d "$(distdir)/$$file"; then \
-+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-+ fi; \
-+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-+ fi; \
-+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-+ else \
-+ test -f "$(distdir)/$$file" \
-+ || cp -p $$d/$$file "$(distdir)/$$file" \
-+ || exit 1; \
-+ fi; \
-+ done
-+check-am: all-am
-+check: check-am
-+all-am: Makefile all-local
-+installdirs:
-+install: install-am
-+install-exec: install-exec-am
-+install-data: install-data-am
-+uninstall: uninstall-am
-+
-+install-am: all-am
-+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-+
-+installcheck: installcheck-am
-+install-strip:
-+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-+ `test -z '$(STRIP)' || \
-+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-+mostlyclean-generic:
-+
-+clean-generic:
-+
-+distclean-generic:
-+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-+
-+maintainer-clean-generic:
-+ @echo "This command is intended for maintainers to use"
-+ @echo "it deletes files that may require special tools to rebuild."
-+clean: clean-am
-+
-+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
-+
-+distclean: distclean-am
-+ -rm -f Makefile
-+distclean-am: clean-am distclean-generic
-+
-+dvi: dvi-am
-+
-+dvi-am:
-+
-+html: html-am
-+
-+html-am:
-+
-+info: info-am
-+
-+info-am:
-+
-+install-data-am:
-+
-+install-dvi: install-dvi-am
-+
-+install-dvi-am:
-+
-+install-exec-am: install-exec-local
-+
-+install-html: install-html-am
-+
-+install-html-am:
-+
-+install-info: install-info-am
-+
-+install-info-am:
-+
-+install-man:
-+
-+install-pdf: install-pdf-am
-+
-+install-pdf-am:
-+
-+install-ps: install-ps-am
-+
-+install-ps-am:
-+
-+installcheck-am:
-+
-+maintainer-clean: maintainer-clean-am
-+ -rm -f Makefile
-+maintainer-clean-am: distclean-am maintainer-clean-generic
-+
-+mostlyclean: mostlyclean-am
-+
-+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
-+
-+pdf: pdf-am
-+
-+pdf-am:
-+
-+ps: ps-am
-+
-+ps-am:
-+
-+uninstall-am:
-+
-+.MAKE: install-am install-strip
-+
-+.PHONY: all all-am all-local check check-am clean clean-generic \
-+ clean-libtool clean-local distclean distclean-generic \
-+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
-+ install install-am install-data install-data-am install-dvi \
-+ install-dvi-am install-exec install-exec-am install-exec-local \
-+ install-html install-html-am install-info install-info-am \
-+ install-man install-pdf install-pdf-am install-ps \
-+ install-ps-am install-strip installcheck installcheck-am \
-+ installdirs maintainer-clean maintainer-clean-generic \
-+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
-+ ps ps-am uninstall uninstall-am
-+
-+export XA_SRCDIR
-+export XA_TOPSRCDIR
-+export XA_ABSTOPSRCDIR
-+
-+all-local: user-all-local
-+
-+install-exec-local: user-install-local
-+
-+clean-local: user-clean-local
-+
-+user-all-local:
-+ ${MAKE} ${_mcall} all;
-+
-+# Have no user-install-data-local ATM
-+user-install-local: user-install-exec-local
-+
-+user-install-exec-local:
-+ ${MAKE} ${_mcall} install;
-+
-+user-clean-local:
-+ ${MAKE} ${_mcall} clean;
-+
-+# Tell versions [3.59,3.63) of GNU make to not export all variables.
-+# Otherwise a system limit (for SysV at least) may be exceeded.
-+.NOEXPORT:
-+
---- /dev/null
-+++ b/extensions/LUA/Makefile.am
-@@ -0,0 +1 @@
-+include ../../Makefile.extra
---- /dev/null
-+++ b/extensions/LUA/Makefile.in
-@@ -0,0 +1,389 @@
-+# Makefile.in generated by automake 1.11.1 from Makefile.am.
-+# @configure_input@
-+
-+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-+# Inc.
-+# This Makefile.in is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-+
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-+# PARTICULAR PURPOSE.
-+
-+@SET_MAKE@
-+
-+# -*- Makefile -*-
-+# AUTOMAKE
-+VPATH = @srcdir@
-+pkgdatadir = $(datadir)/@PACKAGE@
-+pkgincludedir = $(includedir)/@PACKAGE@
-+pkglibdir = $(libdir)/@PACKAGE@
-+pkglibexecdir = $(libexecdir)/@PACKAGE@
-+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-+install_sh_DATA = $(install_sh) -c -m 644
-+install_sh_PROGRAM = $(install_sh) -c
-+install_sh_SCRIPT = $(install_sh) -c
-+INSTALL_HEADER = $(INSTALL_DATA)
-+transform = $(program_transform_name)
-+NORMAL_INSTALL = :
-+PRE_INSTALL = :
-+POST_INSTALL = :
-+NORMAL_UNINSTALL = :
-+PRE_UNINSTALL = :
-+POST_UNINSTALL = :
-+build_triplet = @build@
-+host_triplet = @host@
-+DIST_COMMON = $(srcdir)/../../Makefile.extra $(srcdir)/Makefile.am \
-+ $(srcdir)/Makefile.in
-+subdir = extensions/LUA
-+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-+am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
-+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
-+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
-+ $(top_srcdir)/configure.ac
-+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
-+ $(ACLOCAL_M4)
-+mkinstalldirs = $(install_sh) -d
-+CONFIG_HEADER = $(top_builddir)/config.h
-+CONFIG_CLEAN_FILES =
-+CONFIG_CLEAN_VPATH_FILES =
-+SOURCES =
-+DIST_SOURCES =
-+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-+ACLOCAL = @ACLOCAL@
-+AMTAR = @AMTAR@
-+AR = @AR@
-+AUTOCONF = @AUTOCONF@
-+AUTOHEADER = @AUTOHEADER@
-+AUTOMAKE = @AUTOMAKE@
-+AWK = @AWK@
-+CC = @CC@
-+CCDEPMODE = @CCDEPMODE@
-+CFLAGS = @CFLAGS@
-+CPP = @CPP@
-+CPPFLAGS = @CPPFLAGS@
-+CYGPATH_W = @CYGPATH_W@
-+DEFS = @DEFS@
-+DEPDIR = @DEPDIR@
-+DSYMUTIL = @DSYMUTIL@
-+DUMPBIN = @DUMPBIN@
-+ECHO_C = @ECHO_C@
-+ECHO_N = @ECHO_N@
-+ECHO_T = @ECHO_T@
-+EGREP = @EGREP@
-+EXEEXT = @EXEEXT@
-+FGREP = @FGREP@
-+GREP = @GREP@
-+INSTALL = @INSTALL@
-+INSTALL_DATA = @INSTALL_DATA@
-+INSTALL_PROGRAM = @INSTALL_PROGRAM@
-+INSTALL_SCRIPT = @INSTALL_SCRIPT@
-+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-+LD = @LD@
-+LDFLAGS = @LDFLAGS@
-+LIBOBJS = @LIBOBJS@
-+LIBS = @LIBS@
-+LIBTOOL = @LIBTOOL@
-+LIPO = @LIPO@
-+LN_S = @LN_S@
-+LTLIBOBJS = @LTLIBOBJS@
-+MAKEINFO = @MAKEINFO@
-+MKDIR_P = @MKDIR_P@
-+NM = @NM@
-+NMEDIT = @NMEDIT@
-+OBJDUMP = @OBJDUMP@
-+OBJEXT = @OBJEXT@
-+OTOOL = @OTOOL@
-+OTOOL64 = @OTOOL64@
-+PACKAGE = @PACKAGE@
-+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-+PACKAGE_NAME = @PACKAGE_NAME@
-+PACKAGE_STRING = @PACKAGE_STRING@
-+PACKAGE_TARNAME = @PACKAGE_TARNAME@
-+PACKAGE_URL = @PACKAGE_URL@
-+PACKAGE_VERSION = @PACKAGE_VERSION@
-+PATH_SEPARATOR = @PATH_SEPARATOR@
-+PKG_CONFIG = @PKG_CONFIG@
-+RANLIB = @RANLIB@
-+SED = @SED@
-+SET_MAKE = @SET_MAKE@
-+SHELL = @SHELL@
-+STRIP = @STRIP@
-+VERSION = @VERSION@
-+abs_builddir = @abs_builddir@
-+abs_srcdir = @abs_srcdir@
-+abs_top_builddir = @abs_top_builddir@
-+abs_top_srcdir = @abs_top_srcdir@
-+ac_ct_CC = @ac_ct_CC@
-+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-+am__include = @am__include@
-+am__leading_dot = @am__leading_dot@
-+am__quote = @am__quote@
-+am__tar = @am__tar@
-+am__untar = @am__untar@
-+bindir = @bindir@
-+build = @build@
-+build_alias = @build_alias@
-+build_cpu = @build_cpu@
-+build_os = @build_os@
-+build_vendor = @build_vendor@
-+builddir = @builddir@
-+datadir = @datadir@
-+datarootdir = @datarootdir@
-+docdir = @docdir@
-+dvidir = @dvidir@
-+exec_prefix = @exec_prefix@
-+host = @host@
-+host_alias = @host_alias@
-+host_cpu = @host_cpu@
-+host_os = @host_os@
-+host_vendor = @host_vendor@
-+htmldir = @htmldir@
-+includedir = @includedir@
-+infodir = @infodir@
-+install_sh = @install_sh@
-+kbuilddir = @kbuilddir@
-+kinclude_CFLAGS = @kinclude_CFLAGS@
-+ksourcedir = @ksourcedir@
-+libdir = @libdir@
-+libexecdir = @libexecdir@
-+libxtables_CFLAGS = @libxtables_CFLAGS@
-+libxtables_LIBS = @libxtables_LIBS@
-+localedir = @localedir@
-+localstatedir = @localstatedir@
-+lt_ECHO = @lt_ECHO@
-+mandir = @mandir@
-+mkdir_p = @mkdir_p@
-+oldincludedir = @oldincludedir@
-+pdfdir = @pdfdir@
-+prefix = @prefix@
-+program_transform_name = @program_transform_name@
-+psdir = @psdir@
-+regular_CFLAGS = @regular_CFLAGS@
-+sbindir = @sbindir@
-+sharedstatedir = @sharedstatedir@
-+srcdir = @srcdir@
-+sysconfdir = @sysconfdir@
-+target_alias = @target_alias@
-+top_build_prefix = @top_build_prefix@
-+top_builddir = @top_builddir@
-+top_srcdir = @top_srcdir@
-+xtlibdir = @xtlibdir@
-+XA_SRCDIR = ${srcdir}
-+XA_TOPSRCDIR = ${top_srcdir}
-+XA_ABSTOPSRCDIR = ${abs_top_srcdir}
-+_mcall = -f ${top_builddir}/Makefile.iptrules
-+all: all-am
-+
-+.SUFFIXES:
-+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/../../Makefile.extra $(am__configure_deps)
-+ @for dep in $?; do \
-+ case '$(am__configure_deps)' in \
-+ *$$dep*) \
-+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
-+ && { if test -f $@; then exit 0; else break; fi; }; \
-+ exit 1;; \
-+ esac; \
-+ done; \
-+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign extensions/LUA/Makefile'; \
-+ $(am__cd) $(top_srcdir) && \
-+ $(AUTOMAKE) --foreign extensions/LUA/Makefile
-+.PRECIOUS: Makefile
-+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
-+ @case '$?' in \
-+ *config.status*) \
-+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
-+ *) \
-+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
-+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
-+ esac;
-+
-+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
-+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-+
-+$(top_srcdir)/configure: $(am__configure_deps)
-+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
-+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-+$(am__aclocal_m4_deps):
-+
-+mostlyclean-libtool:
-+ -rm -f *.lo
-+
-+clean-libtool:
-+ -rm -rf .libs _libs
-+tags: TAGS
-+TAGS:
-+
-+ctags: CTAGS
-+CTAGS:
-+
-+
-+distdir: $(DISTFILES)
-+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
-+ list='$(DISTFILES)'; \
-+ dist_files=`for file in $$list; do echo $$file; done | \
-+ sed -e "s|^$$srcdirstrip/||;t" \
-+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
-+ case $$dist_files in \
-+ */*) $(MKDIR_P) `echo "$$dist_files" | \
-+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
-+ sort -u` ;; \
-+ esac; \
-+ for file in $$dist_files; do \
-+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
-+ if test -d $$d/$$file; then \
-+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
-+ if test -d "$(distdir)/$$file"; then \
-+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-+ fi; \
-+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
-+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
-+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
-+ fi; \
-+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
-+ else \
-+ test -f "$(distdir)/$$file" \
-+ || cp -p $$d/$$file "$(distdir)/$$file" \
-+ || exit 1; \
-+ fi; \
-+ done
-+check-am: all-am
-+check: check-am
-+all-am: Makefile all-local
-+installdirs:
-+install: install-am
-+install-exec: install-exec-am
-+install-data: install-data-am
-+uninstall: uninstall-am
-+
-+install-am: all-am
-+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-+
-+installcheck: installcheck-am
-+install-strip:
-+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-+ `test -z '$(STRIP)' || \
-+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-+mostlyclean-generic:
-+
-+clean-generic:
-+
-+distclean-generic:
-+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-+
-+maintainer-clean-generic:
-+ @echo "This command is intended for maintainers to use"
-+ @echo "it deletes files that may require special tools to rebuild."
-+clean: clean-am
-+
-+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
-+
-+distclean: distclean-am
-+ -rm -f Makefile
-+distclean-am: clean-am distclean-generic
-+
-+dvi: dvi-am
-+
-+dvi-am:
-+
-+html: html-am
-+
-+html-am:
-+
-+info: info-am
-+
-+info-am:
-+
-+install-data-am:
-+
-+install-dvi: install-dvi-am
-+
-+install-dvi-am:
-+
-+install-exec-am: install-exec-local
-+
-+install-html: install-html-am
-+
-+install-html-am:
-+
-+install-info: install-info-am
-+
-+install-info-am:
-+
-+install-man:
-+
-+install-pdf: install-pdf-am
-+
-+install-pdf-am:
-+
-+install-ps: install-ps-am
-+
-+install-ps-am:
-+
-+installcheck-am:
-+
-+maintainer-clean: maintainer-clean-am
-+ -rm -f Makefile
-+maintainer-clean-am: distclean-am maintainer-clean-generic
-+
-+mostlyclean: mostlyclean-am
-+
-+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
-+
-+pdf: pdf-am
-+
-+pdf-am:
-+
-+ps: ps-am
-+
-+ps-am:
-+
-+uninstall-am:
-+
-+.MAKE: install-am install-strip
-+
-+.PHONY: all all-am all-local check check-am clean clean-generic \
-+ clean-libtool clean-local distclean distclean-generic \
-+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
-+ install install-am install-data install-data-am install-dvi \
-+ install-dvi-am install-exec install-exec-am install-exec-local \
-+ install-html install-html-am install-info install-info-am \
-+ install-man install-pdf install-pdf-am install-ps \
-+ install-ps-am install-strip installcheck installcheck-am \
-+ installdirs maintainer-clean maintainer-clean-generic \
-+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
-+ ps ps-am uninstall uninstall-am
-+
-+export XA_SRCDIR
-+export XA_TOPSRCDIR
-+export XA_ABSTOPSRCDIR
-+
-+all-local: user-all-local
-+
-+install-exec-local: user-install-local
-+
-+clean-local: user-clean-local
-+
-+user-all-local:
-+ ${MAKE} ${_mcall} all;
-+
-+# Have no user-install-data-local ATM
-+user-install-local: user-install-exec-local
-+
-+user-install-exec-local:
-+ ${MAKE} ${_mcall} install;
-+
-+user-clean-local:
-+ ${MAKE} ${_mcall} clean;
-+
-+# Tell versions [3.59,3.63) of GNU make to not export all variables.
-+# Otherwise a system limit (for SysV at least) may be exceeded.
-+.NOEXPORT:
-+
---- /dev/null
-+++ b/extensions/LUA/Mbuild
-@@ -0,0 +1,3 @@
-+# -*- Makefile -*-
-+
-+obj-${build_LUA} += libxt_LUA.so
---- /dev/null
-+++ b/extensions/LUA/nf_lua.c
-@@ -0,0 +1,64 @@
-+#if defined(__KERNEL__)
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+
-+#endif
-+
-+#include "lua.h"
-+#include "lobject.h" /*sizeof(udata) */
-+#include "lauxlib.h"
-+#include "controller.h"
-+
-+#if defined(__KERNEL__) /* reachs until luaopen_nflib */
-+
-+
-+static int32_t nf_get_random(lua_State *L)
-+{
-+ uint32_t rand = 0;
-+
-+ get_random_bytes(&rand, sizeof(uint32_t ));
-+ lua_pushnumber(L, rand);
-+ return 1;
-+}
-+
-+static int32_t nf_get_time(lua_State *L)
-+{
-+ lua_pushnumber(L, jiffies_to_msecs(jiffies_64));
-+ return 1;
-+}
-+
-+static const struct luaL_Reg nf_lua_lib_f [] = {
-+ { "get_random", nf_get_random },
-+ { "get_time", nf_get_time },
-+ { NULL, NULL }
-+};
-+
-+void luaopen_nflib(lua_State *L)
-+{
-+ int32_t top;
-+
-+ luaL_register(L, NETFILTER_LIB, nf_lua_lib_f);
-+ lua_pop(L, 1);
-+
-+ /* registering verdicts inside the _G */
-+ lua_getglobal(L, "_G");
-+ top = lua_gettop(L);
-+
-+ lua_pushinteger(L, XT_CONTINUE);
-+ lua_setfield(L, top, "XT_CONTINUE"); /* continiue with next rule */
-+
-+ lua_pushinteger(L, NF_DROP);
-+ lua_setfield(L, top, "NF_DROP"); /* stop traversal in the current table hook and drop packet */
-+
-+ lua_pushinteger(L, NF_ACCEPT);
-+ lua_setfield(L, top, "NF_ACCEPT"); /* stop traversal in the current table hook and accept packet */
-+
-+ lua_pop(L, 1); /* pop _G */
-+}
-+
-+#endif
---- /dev/null
-+++ b/extensions/LUA/prot_buf_dynamic.c
-@@ -0,0 +1,486 @@
-+/*
-+ * Copyright (C) 2010 University of Basel
-+ * by Andre Graf
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, see .
-+ */
-+
-+#include "controller.h"
-+
-+
-+
-+struct protocol_buf * dyn_prot_buf_array[MAX_NR_OF_DYN_PROT_BUFS] = { NULL };
-+
-+
-+/* LUA_API: the function 'field_dynamic_setter' acts as a wrapper around
-+ * a given Lua field setter function of a dynamic protocol buffer. The
-+ * string containing the lua function name was piggybacked in the 'set'
-+ * member of the protocol_field. We call this function passing the actual
-+ * segment as byte array and the set value.
-+ *
-+ * Paramters:
-+ * 1. lua_packet_segment (implicit)
-+ * 2. some lua value
-+ *
-+ * Upvalues:
-+ * 1. pointer to the protocol buffer
-+ * 2. field index
-+ *
-+ * Returns:
-+ * 1. true or false if the 'set' was successful
-+ */
-+int32_t field_dynamic_setter(lua_State *L)
-+{
-+ size_t nbytes;
-+ lua_packet_segment * array;
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+ int32_t field_index = lua_tointeger(L, lua_upvalueindex(2));
-+
-+ /* the function name is piggybacked as a string */
-+ lua_getglobal(L, (char *)prot_buf->protocol_fields[field_index].set);
-+ if (!lua_isfunction(L, -1)) {
-+ lua_pushboolean(L, 0);
-+ return 1;
-+ }
-+
-+ nbytes = sizeof(lua_packet_segment) + seg->length * sizeof(uint8_t);
-+ array = (lua_packet_segment *)lua_newuserdata(L, nbytes);
-+ array->length = seg->length;
-+ array->start = seg->start + seg->offset;
-+ array->changes = NULL;
-+
-+ luaL_getmetatable(L, LUA_BYTE_ARRAY);
-+ lua_setmetatable(L, -2);
-+ lua_pushvalue(L, 2); /* push value to set */
-+ if (lua_pcall(L, 2, 1, 0) != 0) {
-+ pr_debug("Error: %s \n", lua_tostring(L, -1));
-+ lua_pop(L, 1);
-+ lua_pushboolean(L, 0);
-+ }
-+ return 1;
-+}
-+
-+/* LUA_API: the function 'field_dynamic_getter' acts as a wrapper around
-+ * a given Lua field getter function of a dynamic protocol buffer. The
-+ * string containing the lua function name was piggybacked in the 'get'
-+ * member of the protocol_field. We call this function passing the actual
-+ * segment as byte array.
-+ *
-+ * Paramters:
-+ * 1. lua_packet_segment (implicit)
-+ *
-+ * Upvalues:
-+ * 1. pointer to the protocol buffer
-+ * 2. field index
-+ *
-+ * Returns:
-+ * 1. true or false if the 'get' was successful
-+ */
-+int32_t field_dynamic_getter(lua_State *L)
-+{
-+ size_t nbytes;
-+ lua_packet_segment * array;
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+ int32_t field_index = lua_tointeger(L, lua_upvalueindex(2));
-+
-+ /* the function name is piggybacked as a string */
-+ lua_getglobal(L, (char *)prot_buf->protocol_fields[field_index].get);
-+ if (!lua_isfunction(L, -1)) {
-+ lua_pushboolean(L, 0);
-+ return 1;
-+ }
-+
-+ nbytes = sizeof(lua_packet_segment) + seg->length * sizeof(uint8_t);
-+ array = (lua_packet_segment *)lua_newuserdata(L, nbytes);
-+ array->length = seg->length;
-+ array->start = seg->start + seg->offset;
-+ array->changes = NULL;
-+
-+ luaL_getmetatable(L, LUA_BYTE_ARRAY);
-+ lua_setmetatable(L, -2);
-+ if (lua_pcall(L, 1, 1, 0) != 0) {
-+ pr_debug("Error: %s \n", luaL_checkstring(L, -1));
-+ lua_pop(L, 1);
-+ lua_pushboolean(L, 0);
-+ }
-+ return 1;
-+}
-+
-+/* LUA_API: the function 'has_protocol_dynamic' acts as a wrapper around
-+ * a given lua has_protocol function of a dynamic protocol buffer. The
-+ * string containing the lua function name was piggybacked in the 'has_protocol'
-+ * member of the protocol_buffer. We call this function passing the actual
-+ * segment.
-+ *
-+ * Paramters:
-+ * 1. lua_packet_segment
-+ * 2. protocol type
-+ *
-+ * Returns:
-+ * 1. true or false if the payload field contains the given protocol
-+ */
-+int32_t has_protocol_dynamic(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t type)
-+{
-+ lua_packet_segment *seg_new;
-+ int32_t res = 0;
-+
-+ /* the function name is piggybacked as a string */
-+ lua_getglobal(L, (char *)prot_buf->has_protocol);
-+ seg_new = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
-+ seg_new->start = seg->start;
-+ seg_new->offset = seg->offset;
-+ seg_new->length = seg->length;
-+ seg_new->changes = NULL;
-+ luaL_getmetatable(L, prot_buf->name);
-+ lua_setmetatable(L, -2);
-+ lua_pushinteger(L, type); /* push the protocol type */
-+ if (lua_pcall(L, 2, 1, 0) != 0) {
-+ pr_debug("Error: %s \n", luaL_checkstring(L, -1));
-+ lua_pop(L, 1);
-+ return 0;
-+ }
-+ res = lua_toboolean(L, -1);
-+ lua_pop(L, 1);
-+
-+ return res;
-+}
-+
-+/* LUA_API: the function 'get_field_changes_dynamic' acts as a wrapper around
-+ * a given lua get_field_changes function of a dynamic protocol buffer. The
-+ * string containing the lua function name was piggybacked in the 'get_field_changes'
-+ * member of the protocol_buffer. We call this function passing the actual
-+ * segment. The lua function must return two lua table containing the offset
-+ * and length changes (in bits).
-+ *
-+ * Paramters:
-+ * 1. lua_packet_segment
-+ *
-+ * Returns:
-+ * 1. new allocated field_changes struct
-+ */
-+struct field_changes * get_field_changes_dynamic(lua_State *L, struct protocol_buf *prot_buf, lua_packet_segment * seg)
-+{
-+ lua_packet_segment *seg_new;
-+ struct field_changes * changes;
-+ int32_t nr_of_changes, i;
-+
-+ lua_getglobal(L, (char *)prot_buf->get_field_changes);
-+
-+ seg_new = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
-+ seg_new->start = seg->start;
-+ seg_new->offset = seg->offset;
-+ seg_new->length = seg->length;
-+ seg_new->changes = NULL;
-+ luaL_getmetatable(L, prot_buf->name);
-+ lua_setmetatable(L, -2);
-+
-+ if (lua_pcall(L, 1, 2, 0) != 0)
-+ luaL_error(L, "inside get_field_changes_dynamic. %s\n", lua_tostring(L, -1));
-+
-+ /* the function call must return a table containing length changes */
-+ luaL_checktype(L, -1, LUA_TTABLE);
-+ /* the function call must return a table containing offset changes */
-+ luaL_checktype(L, -2, LUA_TTABLE);
-+ /* both tables have to be of same size */
-+ if (lua_objlen(L, -1) != lua_objlen(L, -2))
-+ luaL_error(L, "the provided tables are not of equal size");
-+
-+ nr_of_changes = lua_objlen(L, -1);
-+ changes = get_allocated_field_changes(L, nr_of_changes);
-+
-+ /* loop over the tables */
-+ for (i = 1; i < nr_of_changes; i++) {
-+ lua_rawgeti(L, -1, i); /* push length value of field at index i */
-+ changes->field_length_changes[i - 1] = luaL_checkinteger(L, -1);
-+ lua_pop(L, 1); /* pop offset value */
-+
-+ lua_rawgeti(L, -2, i); /* push offset value of field at index i */
-+ changes->field_offset_changes[i - 1] = luaL_checkinteger(L, -1);
-+ lua_pop(L, 1); /* pop length value */
-+ }
-+
-+ /* pop both tables */
-+ lua_pop(L, 2);
-+
-+ return changes;
-+}
-+
-+/* C_INT: 'get_free_protocol_index' is only used internally. This function
-+ * gets a free slot inside the array holding all the protocol buffers.
-+ * There are several ways to get to this information. In this case I take
-+ * the way over the reflected array SUPPORTED_PROTOCOL_TABLE inside the
-+ * Lua state. Since this function is called at laodtime, we do not have
-+ * to care about performance.
-+ */
-+static int32_t get_free_protocol_index(lua_State *L)
-+{
-+ int32_t protocol_index;
-+
-+ lua_getglobal(L, SUPPORTED_PROTOCOL_TABLE);
-+ protocol_index = lua_objlen(L, -1) + 1;
-+ lua_pop(L, 1);
-+ return protocol_index;
-+}
-+
-+/* C_API: 'free_dynamic_prot_buf' frees the allocated memory of a given
-+ * dynamic protocol buffer. this function is normally called inside a
-+ * cleanup routine. Be aware, before running this function you must be
-+ * sure that no references to the dynamic protocol buffers were available.
-+ * It's recomended to close the Lua state before calling the function. */
-+void free_dynamic_prot_buf(struct protocol_buf * prot_buf)
-+{
-+ struct protocol_field * field = prot_buf->protocol_fields;
-+
-+ for (; field->name != NULL; field++) {
-+ if (field->get) kfree(field->get);
-+ if (field->set) kfree(field->set);
-+ if (field->name) kfree((char *)field->name);
-+ }
-+
-+ if (prot_buf->payload_field) kfree(prot_buf->payload_field);
-+ if (prot_buf->has_protocol) kfree(prot_buf->has_protocol);
-+
-+ if (prot_buf->get_field_changes) kfree(prot_buf->get_field_changes);
-+ kfree((char *)prot_buf->name);
-+ kfree(prot_buf);
-+ return;
-+}
-+
-+void cleanup_dynamic_prot_bufs(void)
-+{
-+ int32_t i;
-+
-+ for (i = 0; i < MAX_NR_OF_DYN_PROT_BUFS; i++) {
-+ if (dyn_prot_buf_array[i]) {
-+ free_dynamic_prot_buf(dyn_prot_buf_array[i]);
-+ dyn_prot_buf_array[i] = NULL;
-+ }
-+ }
-+ return;
-+}
-+
-+
-+/* C_INT: 'free_protocol_fields' is used internally as a helper function for
-+ * 'register_dynamic_protbuf'. It is used when durin registration an error
-+ * occurs and the afore allocated fields needed to be freed. */
-+static inline void free_protocol_fields(struct protocol_field * prot_fields, int32_t i)
-+{
-+ struct protocol_field * f;
-+
-+ while (i >= 0) {
-+ f = &prot_fields[i];
-+ if (f->name) kfree((void *)f->name);
-+ if (f->get) kfree((void *)f->get);
-+ if (f->set) kfree((void *)f->set);
-+ kfree((void *)f);
-+ i--;
-+ }
-+}
-+
-+/* LUA_API: 'register_dynamic_protbuf' is called from within the Lua script.
-+ * it takes a Lua table representing the dynamic protocol buffer as parameter.
-+ * e.g.:
-+ * eth_prot_buf = {
-+ * name = "packet_eth_dyn",
-+ * payload_field = "data",
-+ * protocol_fields = {
-+ * {"dmac", 0, 48, nil, nil },
-+ * {"smac", 48, 48, nil, nil },
-+ * {"type", 96, 16, nil, nil },
-+ * {"data", 112, 0, nil, nil },
-+ * },
-+ * has_protocol = "eth_dyn_has_protocol",
-+ * get_field_changes = "eth_dyn_get_field_changes"
-+ * }
-+ * register_dynamic_protbuf(eth_prot_buf)
-+ *
-+ * the table gets parsed and a new protocol_buf struct is allocated and
-+ * initialized using 'register_protbuf', which is also used for the static
-+ * protocol buffers. This enables an identical behavior like the static
-+ * protocol buffers. The dynamic protocol buffers are not garbage collected,
-+ * use 'free_dynamic_protbuf' to free them after closing the Lua state.
-+ */
-+static int32_t register_dynamic_protbuf(lua_State *L)
-+{
-+ struct protocol_buf *prot_buf;
-+ struct protocol_field *field, sentinel = PROT_FIELD_SENTINEL;
-+ int32_t nr_of_fields, i;
-+
-+ prot_buf = (struct protocol_buf *)kmalloc(sizeof(struct protocol_buf), GFP_KERNEL);
-+ prot_buf->is_dynamic = 1;
-+
-+ /* check if parameter is a table */
-+ luaL_checktype(L, 1, LUA_TTABLE);
-+
-+ /* initialize prot_buf.name */
-+ lua_getfield(L, 1, "name");
-+ prot_buf->name = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
-+ strcpy((char *)prot_buf->name, luaL_checkstring(L, -1));
-+ lua_pop(L, 1); /* pop res from lua_getfield */
-+
-+ /* check if protocol buffer is already registered */
-+ lua_getglobal(L, prot_buf->name);
-+ if (!lua_isnil(L, -1)) {
-+ lua_pop(L, 1); /* pop res from lua_getglobal */
-+ pr_debug("protocol_buf '%s' already registered.\n", prot_buf->name);
-+ goto free_prot_buf;
-+ }
-+ lua_pop(L, 1); /* pop res from lua_getglobal */
-+
-+ /* initialize payload field */
-+ lua_getfield(L, 1, "payload_field");
-+ if (lua_isstring(L, -1)) {
-+ prot_buf->payload_field = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
-+ strcpy(prot_buf->payload_field, lua_tostring(L, -1));
-+ }else
-+ prot_buf->payload_field = NULL;
-+ lua_pop(L, 1); /* pop res from lua_getfield */
-+
-+ /* initialize protocol_fields field*/
-+ lua_getfield(L, 1, "protocol_fields");
-+ if (!lua_istable(L, -1)) {
-+ pr_debug("invalid protocol_fields table.\n");
-+ goto err2;
-+
-+ }
-+
-+ nr_of_fields = lua_objlen(L, -1);
-+ prot_buf->protocol_fields = (struct protocol_field *)kmalloc((nr_of_fields + 1) * sizeof(struct protocol_field), GFP_KERNEL);
-+
-+ for (i = 1; i <= nr_of_fields; i++) {
-+ field = &prot_buf->protocol_fields[i - 1];
-+ /* initialize protocol field */
-+ lua_rawgeti(L, -1, i); /* push field-table */
-+ if (!lua_istable(L, -1)) {
-+ free_protocol_fields(prot_buf->protocol_fields, i);
-+ pr_debug("invalid protocol_field at %i.\n", i);
-+ goto err;
-+ }
-+
-+ /* initialize protocol field name */
-+ lua_rawgeti(L, -1, 1);
-+ if (!lua_isstring(L, -1)) {
-+ free_protocol_fields(prot_buf->protocol_fields, i);
-+ pr_debug("invalid protocol_field name at %i.\n", i);
-+ goto err;
-+ }
-+
-+ field->name = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
-+ strcpy((char*)field->name, lua_tostring(L, -1));
-+ lua_pop(L, 1); /* pop field name */
-+
-+ /* initialize protocol field offset */
-+ lua_rawgeti(L, -1, 2);
-+ if (!lua_isnumber(L, -1)) {
-+ free_protocol_fields(prot_buf->protocol_fields, i);
-+ pr_debug("invalid protocol_field offset at %i.\n", i);
-+ goto err;
-+ }
-+ field->offset = lua_tointeger(L, -1);
-+ lua_pop(L, 1); /* pop field offset */
-+
-+ /* initialize protocol field length */
-+ lua_rawgeti(L, -1, 3);
-+ if (!lua_isnumber(L, -1)) {
-+ free_protocol_fields(prot_buf->protocol_fields, i);
-+ pr_debug("invalid protocol_field length at %i.\n", i);
-+ goto err;
-+ }
-+ field->length = lua_tointeger(L, -1);
-+ lua_pop(L, 1); /* pop field length */
-+
-+ /* initialize protocol field getter */
-+ lua_rawgeti(L, -1, 4);
-+ if (lua_isstring(L, -1)) {
-+ field->get = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
-+ strcpy((char *)field->get, lua_tostring(L, -1)); /* the get-wrapper knows about the piggybacked string */
-+ }else
-+ field->get = NULL;
-+ lua_pop(L, 1); /* pop field getter */
-+
-+ /* initialize protocol field setter */
-+ lua_rawgeti(L, -1, 5);
-+ if (lua_isstring(L, -1)) {
-+ field->set = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
-+ strcpy((char *)field->set, lua_tostring(L, -1)); /* the set-wrapper knows about the piggybacked string */
-+ }else
-+ field->set = NULL;
-+ lua_pop(L, 1); /* pop field setter */
-+
-+ /* field initialization completed */
-+ lua_pop(L, 1); /* pop field-table */
-+ }
-+
-+ /* put sentinel at the end of protocol_fields */
-+ memcpy(&prot_buf->protocol_fields[nr_of_fields], &sentinel, sizeof(sentinel));
-+ lua_pop(L, 1); /* pop protocol-fields-table */
-+
-+ /* initialize has_protocol field */
-+ lua_getfield(L, 1, "has_protocol");
-+ if (lua_isstring(L, -1)) {
-+ prot_buf->has_protocol = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
-+ strcpy((char *)prot_buf->has_protocol, lua_tostring(L, -1)); /* the has_protocol-wrapper knows about the piggybacked string */
-+ }else
-+ prot_buf->has_protocol = NULL;
-+ lua_pop(L, 1); /* pop has_protocol */
-+
-+ /* initialize get_field_changes field */
-+ lua_getfield(L, 1, "get_field_changes");
-+ if (lua_isstring(L, -1)) {
-+ prot_buf->get_field_changes = kmalloc(lua_objlen(L, -1), GFP_KERNEL);
-+ strcpy((char *)prot_buf->get_field_changes, lua_tostring(L, -1)); /* the get_field_changes-wrapper knows about the piggybacked string */
-+ }else
-+ prot_buf->get_field_changes = NULL;
-+ lua_pop(L, 1); /* pop get_field_changes */
-+
-+ /* Storing the pointer to the DYNAMIC protbuf within dyn_prot_buf_array, in order to free it at cleanup */
-+ for (i = 0; i < MAX_NR_OF_DYN_PROT_BUFS; i++) {
-+ if (!dyn_prot_buf_array[i]) {
-+ dyn_prot_buf_array[i] = prot_buf;
-+ break;
-+ }else
-+ goto err;
-+ }
-+
-+ /* call the "common" register_protbuf */
-+ register_protbuf(L, prot_buf, get_free_protocol_index(L)); /* register prot_buf as it is done with the static ones */
-+
-+ return 0;
-+
-+err:
-+ kfree(prot_buf->protocol_fields);
-+err2:
-+ if (prot_buf->payload_field) kfree(prot_buf->payload_field);
-+free_prot_buf:
-+ kfree((void *)prot_buf->name);
-+ kfree(prot_buf);
-+
-+ luaL_error(L, "one or more error happend while registering a dynamic protocol buffer, please consult the debug log");
-+
-+ return 0;
-+
-+}
-+
-+void luaopen_protbuf_dynamic(lua_State *L)
-+{
-+ lua_getglobal(L, "_G");
-+ lua_pushcclosure(L, register_dynamic_protbuf, 0);
-+ lua_setfield(L, -2, "register_dynamic_protbuf");
-+ lua_pop(L, 1); /* pop _G */
-+ return;
-+}
---- /dev/null
-+++ b/extensions/LUA/prot_buf_ethernet.c
-@@ -0,0 +1,60 @@
-+/*
-+ * Copyright (C) 2010 University of Basel
-+ * by Andre Graf
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, see .
-+ */
-+
-+#include "controller.h"
-+
-+
-+static int32_t eth_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
-+{
-+ uint8_t *embedded_protocol = seg->start + seg->offset + 12 /*bytes*/;
-+ unsigned short res = (unsigned short)((embedded_protocol[1] << CHAR_BIT) | (embedded_protocol[0] << CHAR_BIT));
-+
-+ switch (res) {
-+ case 0x0800: /* 1: Internet Protocol (IP) */
-+ if (protocol_type == PACKET_IP) return 1;
-+ break;
-+ default:
-+ return 0;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct protocol_field eth_protocol_fields[] = {
-+ /* field name offset length getter setter */
-+ { "dmac", 0, 48, NULL, NULL },
-+ { "smac", 48, 48, NULL, NULL },
-+ { "type", 96, 16, NULL, NULL },
-+ { "data", 112, 0, NULL, NULL },
-+ PROT_FIELD_SENTINEL,
-+};
-+
-+static const struct protocol_buf eth_protocol_buf = {
-+ .is_dynamic = 0,
-+ .name = LUA_PACKET_SEG_ETH,
-+ .payload_field = "data",
-+ .protocol_fields = (struct protocol_field *)ð_protocol_fields,
-+ .has_protocol = ð_has_protocol,
-+ .get_field_changes = NULL,
-+};
-+
-+
-+void luaopen_protbuf_eth(lua_State *L)
-+{
-+ register_protbuf(L, (struct protocol_buf *)ð_protocol_buf, PACKET_ETH);
-+}
---- /dev/null
-+++ b/extensions/LUA/prot_buf_helpers.c
-@@ -0,0 +1,216 @@
-+/*
-+ * Copyright (C) 2010 University of Basel
-+ * by Andre Graf
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, see .
-+ */
-+
-+#if defined(__KERNEL__)
-+#include
-+#include /* kmalloc */
-+#endif
-+
-+#include "controller.h"
-+
-+int32_t get_header_size(struct protocol_buf * prot_buf)
-+{
-+ int32_t bit_counter = 0;
-+ struct protocol_field * field = prot_buf->protocol_fields;
-+
-+ for (; field->name; field++)
-+ bit_counter += field->length;
-+
-+ return bit_counter >> 3;
-+}
-+
-+
-+int32_t set_32_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+ *(uint32_t *)(seg->start + seg->offset) = (uint32_t )htonl(luaL_checkinteger(L, 2));
-+ return 0;
-+}
-+int32_t get_32_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+ lua_pushinteger(L, ntohl(*((uint32_t *)(seg->start + seg->offset))));
-+ return 1;
-+}
-+
-+int32_t set_16_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+ *(uint16_t *)(seg->start + seg->offset) = (uint16_t)htons(luaL_checkinteger(L, 2));
-+ return 0;
-+}
-+int32_t get_16_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+ lua_pushinteger(L, ntohs(*((uint16_t *)(seg->start + seg->offset))));
-+ return 1;
-+}
-+
-+int32_t set_lower_4_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+ uint8_t b = (uint8_t)luaL_checkinteger(L, 2) << 4;
-+ uint8_t * pos = (uint8_t *)(seg->start + seg->offset);
-+
-+ *pos &= 0x0F; /* reset lower 4 bits*/
-+ *pos |= b;
-+
-+ return 0;
-+}
-+
-+int32_t get_lower_4_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+ lua_pushinteger(L, (*(uint8_t *)(seg->start + seg->offset)) >> 4);
-+ return 1;
-+}
-+
-+int32_t set_upper_4_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+ uint8_t b = (uint8_t)luaL_checkinteger(L, 2) << 4;
-+ uint8_t * pos = (uint8_t *)(seg->start + seg->offset);
-+
-+ *pos &= 0xF0; /* reset upper 4 bits*/
-+ *pos |= (b >> 4);
-+
-+ return 0;
-+}
-+
-+int32_t get_upper_4_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+ lua_pushinteger(L, (*(uint8_t *)(seg->start + seg->offset)) & 0x0F);
-+ return 1;
-+}
-+
-+
-+int32_t set_8_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+ *(uint8_t *)(seg->start + seg->offset) = (uint8_t)luaL_checkinteger(L, 2);
-+ return 0;
-+}
-+
-+int32_t get_8_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+ lua_pushinteger(L, *(uint8_t *)(seg->start + seg->offset));
-+ return 1;
-+}
-+
-+int32_t set_1_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+ unsigned long l = 0;
-+
-+ memcpy(&l, (seg->start + seg->offset), seg->length);
-+ l |= (1 << ((CHAR_BIT * seg->length) - luaL_checkinteger(L, 2)));
-+ memcpy((seg->start + seg->offset), &l, seg->length);
-+
-+ return 0;
-+}
-+
-+int32_t get_1_bit_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+ unsigned long l = 0;
-+ uint32_t bit = 0;
-+
-+ memcpy(&l, (seg->start + seg->offset), seg->length);
-+ bit = l & (1 << ((CHAR_BIT * seg->length) - luaL_checkinteger(L, 2)));
-+
-+ lua_pushboolean(L, bit);
-+ return 1;
-+}
-+
-+int32_t get_string_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+ /* Warning we cast from uchar to char */
-+ lua_pushlstring(L, (char *)seg->start + seg->offset, seg->length);
-+ return 1;
-+}
-+
-+int32_t set_data_generic(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+ lua_packet_segment * data = checkbytearray(L, 2);
-+
-+ pr_debug("seg->length %u, data->length %u\n", seg->length, data->length);
-+
-+ if (seg->length >= data->length)
-+ memcpy((seg->start + seg->offset), data->start, data->length);
-+ else
-+ luaL_error(L, "provided byte array too big for given packet segment");
-+ return 0;
-+}
-+
-+struct field_changes * get_allocated_field_changes(lua_State *L, int32_t nr_of_fields)
-+{
-+ struct field_changes * changes;
-+
-+ changes = kmalloc(sizeof(struct field_changes), GFP_ATOMIC);
-+
-+ if (!changes)
-+ goto failure;
-+
-+ changes->field_length_changes = kmalloc(nr_of_fields * sizeof(int), GFP_ATOMIC);
-+ if (!changes->field_length_changes)
-+ goto free1;
-+
-+ changes->field_offset_changes = kmalloc(nr_of_fields * sizeof(int), GFP_ATOMIC);
-+ if (!changes->field_offset_changes)
-+ goto free2;
-+
-+ memset(changes->field_length_changes, 0, nr_of_fields * sizeof(int));
-+ memset(changes->field_offset_changes, 0, nr_of_fields * sizeof(int));
-+
-+ changes->ref_count = 1;
-+
-+ return changes;
-+
-+free2: kfree(changes->field_length_changes);
-+free1: kfree(changes);
-+failure:
-+ if (!changes) luaL_error(L, "couldnt allocate memory inside 'get_allocated_field_changes'");
-+ return NULL; /* only to omit warnings */
-+}
-\ No newline at end of file
---- /dev/null
-+++ b/extensions/LUA/prot_buf_icmp.c
-@@ -0,0 +1,49 @@
-+/*
-+ * Copyright (C) 2010 University of Basel
-+ * by Andre Graf
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, see .
-+ */
-+
-+#include "controller.h"
-+
-+static int32_t icmp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
-+{
-+ return 0;
-+}
-+
-+static const struct protocol_field icmp_protocol_fields[] = {
-+ /* field name offset length getter setter */
-+ { "type", 0, 8, NULL, NULL },
-+ { "code", 8, 8, NULL, NULL },
-+ { "checksum", 16, 16, NULL, NULL },
-+ { "id", 32, 16, NULL, NULL },
-+ { "sequence", 48, 16, NULL, NULL },
-+ PROT_FIELD_SENTINEL,
-+};
-+
-+static const struct protocol_buf icmp_protocol_buf = {
-+ .is_dynamic = 0,
-+ .name = LUA_PACKET_SEG_ICMP,
-+ .payload_field = NULL,
-+ .protocol_fields = (struct protocol_field *)&icmp_protocol_fields,
-+ .has_protocol = &icmp_has_protocol,
-+ .get_field_changes = NULL,
-+};
-+
-+void luaopen_protbuf_icmp(lua_State *L)
-+{
-+ register_protbuf(L, (struct protocol_buf *)&icmp_protocol_buf, PACKET_ICMP);
-+}
-+
---- /dev/null
-+++ b/extensions/LUA/prot_buf_ip.c
-@@ -0,0 +1,209 @@
-+/*
-+ * Copyright (C) 2010 University of Basel
-+ * by Andre Graf
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, see .
-+ */
-+
-+#if defined(__KERNEL__)
-+ #include
-+ #include
-+#endif
-+
-+#include "controller.h"
-+
-+
-+#define IP_FMT "%u.%u.%u.%u"
-+#define IP_ACC(buf) buf[0], buf[1], buf[2], buf[3]
-+
-+
-+static int32_t ip_version_set(lua_State *L)
-+{
-+ uint8_t version_checked;
-+ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
-+ uint8_t *version_seg = seg->start + seg->offset;
-+ int32_t version = luaL_checkinteger(L, 2);
-+
-+ luaL_argcheck(L, version >= 0 && version <= 15, 1, "version number invalid");
-+
-+ version_checked = (uint8_t)version;
-+
-+ version_seg[0] &= (uint8_t)0x0F; /* reset version bits */
-+ version_seg[0] |= version_checked << 4;
-+
-+ return 0;
-+}
-+static int32_t ip_version_get(lua_State *L)
-+{
-+ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
-+ uint8_t *version_seg = seg->start + seg->offset;
-+ uint8_t v = version_seg[0] & 0xF0;
-+
-+ v >>= 4;
-+
-+ lua_pushinteger(L, v);
-+ return 1;
-+}
-+
-+static int32_t ip_ihl_set(lua_State *L)
-+{
-+ uint8_t ihl_checked;
-+ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
-+ uint8_t *ihl_seg = seg->start + seg->offset;
-+ int32_t ihl = luaL_checkinteger(L, 2);
-+
-+ luaL_argcheck(L, ihl >= 5 && ihl <= 15, 1, "ip header length invalid"); // RFC 791 5x32 = 160 bits
-+
-+ ihl_checked = (uint8_t)ihl;
-+
-+ ihl_seg[0] &= (uint8_t)0xF0; /* reset ihl bits */
-+ ihl_seg[0] |= ihl_checked;
-+
-+ return 0;
-+}
-+static int32_t ip_ihl_get(lua_State *L)
-+{
-+ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
-+ uint8_t *ihl_seg = seg->start + seg->offset;
-+ uint8_t v = ihl_seg[0] & 0x0F;
-+
-+ lua_pushinteger(L, v);
-+ return 1;
-+}
-+
-+static int32_t ip_addr_set(lua_State *L)
-+{
-+ int32_t field_id = lua_tointeger(L, lua_upvalueindex(2));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
-+ uint8_t *addr_seg = seg->start + seg->offset;
-+ uint32_t old_addr;
-+ char *ip = (char *)luaL_checkstring(L, 2);
-+ uint32_t a, b, c, d;
-+ struct sk_buff * skb = (struct sk_buff *)lua_touserdata(L, 3);
-+
-+ /* for tcp / udp checksumming*/
-+ uint32_t prot_offset;
-+ uint8_t *check, *protocol_seg;
-+
-+ /* end */
-+
-+ sscanf(ip, IP_FMT, &a, &b, &c, &d);
-+
-+ luaL_argcheck(L, a < 256 && b < 256 && c < 256 && d < 256, 1, "invalid ip addr");
-+
-+ old_addr = *((uint32_t *)addr_seg);
-+ addr_seg[0] = (uint8_t)a;
-+ addr_seg[1] = (uint8_t)b;
-+ addr_seg[2] = (uint8_t)c;
-+ addr_seg[3] = (uint8_t)d;
-+
-+#if defined(__KERNEL__)
-+ if (old_addr != *(uint32_t *)addr_seg) {
-+ int32_t offset = (field_id == 10) ? -2 : -6; /* offset from saddr or daddr */
-+
-+ csum_replace4((uint16_t *)(addr_seg + offset), old_addr, *(uint32_t *)addr_seg);
-+
-+ prot_offset = (field_id == 10) ? -3 : -7; /* offset from saddr or daddr */
-+ protocol_seg = seg->start + seg->offset + prot_offset;
-+
-+ if (skb && (protocol_seg[0] == 0x06 || protocol_seg[0] == 0x11)) { /* is payload TCP or UDP ? */
-+
-+ check = seg->start + seg->offset; /* tmp res */
-+ check += (field_id == 10) ? 8 : 16; /* the start of the payload, depending saddr or daddr */
-+ check += (protocol_seg[0] == 0x06) ? 16 : 6; /* the start of the checksum, depending on TCP or UDP */
-+
-+ inet_proto_csum_replace4((__sum16 *)check, skb, old_addr, *(uint32_t *)addr_seg, 1);
-+
-+ lua_pop(L, 1);
-+ }
-+ }
-+#endif
-+ return 0;
-+}
-+
-+
-+
-+
-+
-+static int32_t ip_addr_get(lua_State *L)
-+{
-+ lua_packet_segment * seg = checkpacketseg(L, 1, LUA_PACKET_SEG_IP);
-+ uint8_t *addr_seg = seg->start + seg->offset;
-+
-+ char buf[16]; /*max: 255.255.255.255\0 --> 16 chars */
-+
-+ sprintf(buf, IP_FMT, IP_ACC(addr_seg));
-+ lua_pushstring(L, buf);
-+ return 1;
-+}
-+
-+static int32_t ip_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
-+{
-+ uint8_t * embedded_protocol = seg->start + seg->offset + 9 /*bytes*/;
-+
-+ switch (embedded_protocol[0]) {
-+ case 0x01: /* 1: Internet Control Message Protocol (ICMP) */
-+ if (protocol_type == PACKET_ICMP) return 1;
-+ break;
-+ case 0x02: /* 2: Internet Group Management Protocol (IGMP) */
-+ break;
-+ case 0x06: /* 6: Transmission Control Protocol (TCP) */
-+ if (protocol_type == PACKET_TCP) return 1;
-+ break;
-+ case 0x11: /* 17: User Datagram Protocol (UDP) */
-+ if (protocol_type == PACKET_UDP) return 1;
-+ break;
-+ case 0x59: /* 89: Open Shortest Path First (OSPF) */
-+ break;
-+ case 0x84: /* 132: Stream Control Transmission Protocol (SCTP) */
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct protocol_field ip_protocol_fields[] = {
-+ /* field name offset length getter setter */
-+ { "version", 0, 4, ip_version_get, ip_version_set },
-+ { "ihl", 4, 4, ip_ihl_get, ip_ihl_set },
-+ { "tos", 8, 8, get_8_bit_generic, set_8_bit_generic },
-+ { "tot_len", 16, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "id", 32, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "flags", 48, 3, get_1_bit_generic, set_1_bit_generic },
-+ { "frag_off", 51, 13, NULL, NULL },
-+ { "ttl", 64, 8, get_8_bit_generic, set_8_bit_generic },
-+ { "protocol", 72, 8, get_8_bit_generic, set_8_bit_generic },
-+ { "check", 80, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "saddr", 96, 32, ip_addr_get, ip_addr_set },
-+ { "daddr", 128, 32, ip_addr_get, ip_addr_set },
-+ { "data", 160, 0, NULL, set_data_generic },
-+ PROT_FIELD_SENTINEL,
-+};
-+
-+static const struct protocol_buf ip_protocol_buf = {
-+ .is_dynamic = 0,
-+ .name = LUA_PACKET_SEG_IP,
-+ .payload_field = "data",
-+ .protocol_fields = (struct protocol_field *)&ip_protocol_fields,
-+ .has_protocol = &ip_has_protocol,
-+ .get_field_changes = NULL,
-+};
-+
-+void luaopen_protbuf_ip(lua_State *L)
-+{
-+ register_protbuf(L, (struct protocol_buf *)&ip_protocol_buf, PACKET_IP);
-+}
-+
---- /dev/null
-+++ b/extensions/LUA/prot_buf_raw.c
-@@ -0,0 +1,43 @@
-+/*
-+ * Copyright (C) 2010 University of Basel
-+ * by Andre Graf
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, see .
-+ */
-+
-+#include "controller.h"
-+static int32_t raw_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
-+{
-+ return 1;
-+}
-+
-+static const struct protocol_field raw_protocol_fields[] = {
-+ /* field name offset length getter setter */
-+ { "data", 0, 0, NULL, NULL },
-+ PROT_FIELD_SENTINEL,
-+};
-+
-+static const struct protocol_buf raw_protocol_buf = {
-+ .is_dynamic = 0,
-+ .name = LUA_PACKET_SEG_RAW,
-+ .payload_field = "data",
-+ .protocol_fields = (struct protocol_field *)&raw_protocol_fields,
-+ .has_protocol = &raw_has_protocol,
-+ .get_field_changes = NULL,
-+};
-+
-+void luaopen_protbuf_raw(lua_State *L)
-+{
-+ register_protbuf(L, (struct protocol_buf *)&raw_protocol_buf, PACKET_RAW);
-+}
---- /dev/null
-+++ b/extensions/LUA/prot_buf_tcp.c
-@@ -0,0 +1,188 @@
-+/*
-+ * Copyright (C) 2010 University of Basel
-+ * by Andre Graf
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, see .
-+ */
-+
-+#if defined(__KERNEL__)
-+ #include
-+ #include
-+#endif
-+#include "controller.h"
-+
-+
-+static int32_t tcp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
-+{
-+ return 1;
-+}
-+
-+static int32_t tcp_set_checksum(lua_State *L)
-+{
-+ struct protocol_buf * prot_buf = (struct protocol_buf *)lua_topointer(L, lua_upvalueindex(1));
-+ lua_packet_segment * seg = checkpacketseg(L, 1, prot_buf->name);
-+
-+#if defined(__KERNEL__)
-+ uint8_t * check_seg = seg->start + seg->offset;
-+ uint8_t * tcp_hdr = check_seg - 16;
-+ uint8_t * saddr = tcp_hdr - 8;
-+ uint8_t * daddr = saddr + 4;
-+ uint32_t len = 20 + (seg->changes->field_length_changes[11] / 8) + (seg->changes->field_length_changes[10] / 8);
-+ unsigned short checksum = tcp_v4_check(len, *(uint32_t *)saddr, *(uint32_t *)daddr,
-+ csum_partial(tcp_hdr, len, 0));
-+
-+ memcpy(check_seg, &checksum, sizeof(unsigned short));
-+#endif
-+ return 0;
-+}
-+
-+
-+static const struct protocol_field tcp_protocol_fields[] = {
-+ /* field name offset length getter setter */
-+ { "sport", 0, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "dport", 16, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "seq", 32, 32, get_32_bit_generic, set_32_bit_generic },
-+ { "ack", 64, 32, get_32_bit_generic, set_32_bit_generic },
-+ { "data_off", 96, 4, get_lower_4_bit_generic, set_lower_4_bit_generic },
-+ { "reserved", 100, 4, get_upper_4_bit_generic, set_upper_4_bit_generic },
-+ { "flags", 104, 8, get_1_bit_generic, set_1_bit_generic },
-+ { "window_size", 112, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "check", 128, 16, get_16_bit_generic, tcp_set_checksum },
-+ { "urgent", 144, 16, NULL, NULL },
-+ { "options", 160, 0, NULL, set_data_generic },
-+ { "data", 160, 0, NULL, set_data_generic }, /* begin of data depends on options */
-+ PROT_FIELD_SENTINEL,
-+};
-+
-+
-+static const struct protocol_field tcp_options_and_data[] = {
-+ /* field name offset length getter setter */
-+ { "MSS", 0, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "WS", 0, 8, get_8_bit_generic, set_8_bit_generic },
-+ { "SACK", 0, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "TSVAL", 0, 32, get_32_bit_generic, set_32_bit_generic },
-+ { "TSER", 0, 32, get_32_bit_generic, set_32_bit_generic },
-+ PROT_FIELD_SENTINEL,
-+};
-+
-+
-+static struct field_changes * tcp_get_field_changes(lua_State *L, lua_packet_segment * seg);
-+
-+static const struct protocol_buf tcp_protocol_buf = {
-+ .is_dynamic = 0,
-+ .name = LUA_PACKET_SEG_TCP,
-+ .payload_field = "data",
-+ .protocol_fields = (struct protocol_field *)&tcp_protocol_fields,
-+ .has_protocol = &tcp_has_protocol,
-+ .get_field_changes = &tcp_get_field_changes,
-+};
-+
-+
-+static struct field_changes * tcp_options_get_field_changes(lua_State *L, lua_packet_segment * seg);
-+
-+static const struct protocol_buf tcp_options_and_data_buf = {
-+ .is_dynamic = 0,
-+ .name = LUA_PACKET_SEG_TCP_OPT,
-+ .payload_field = NULL,
-+ .protocol_fields = (struct protocol_field *)&tcp_options_and_data,
-+ .has_protocol = NULL,
-+ .get_field_changes = &tcp_options_get_field_changes,
-+};
-+
-+struct field_changes * tcp_get_field_changes(lua_State *L, lua_packet_segment * seg)
-+{
-+ /* depending on the value stored inside the 'data_off'-field, the length of
-+ * the 'options' field has to be changed, as well as the length and offset
-+ * of the 'data' field */
-+ uint8_t *tcp_hdr = seg->start + seg->offset;
-+
-+ /* get the pointer to the 'data_off' field */
-+ uint8_t * data_off_field = tcp_hdr + 12; /* 12 bytes offset */
-+ /* extract the stored header length in bits */
-+ uint32_t tcp_hdr_len = ((*(uint8_t *)data_off_field) >> 4) * 32;
-+
-+ /* get an allocated 'field_changes' structure */
-+ struct field_changes * changes = get_allocated_field_changes(L, 12);
-+
-+ /* depending on the tcp header length, change the length of the options*/
-+ changes->field_length_changes[10] = tcp_hdr_len - 160;
-+ /* depending on the options length, change the offset of the data */
-+ changes->field_offset_changes[11] = changes->field_length_changes[10];
-+ changes->field_length_changes[11] = (seg->length * 8) - tcp_hdr_len;
-+
-+ return changes;
-+
-+}
-+
-+struct field_changes * tcp_options_get_field_changes(lua_State *L, lua_packet_segment * seg)
-+{
-+ /* depending on the value stored inside the 'data_off'-field, the length of
-+ * the 'options' field has to be changed, as well as the length and offset
-+ * of the 'data' field */
-+ uint8_t *tcp_opt_hdr = seg->start + seg->offset;
-+
-+ /* get an allocated 'field_changes' structure */
-+ struct field_changes * changes = get_allocated_field_changes(L, 5);
-+
-+ int32_t MSS = 0, WS = 0, SACK = 0, TS = 0, i;
-+
-+ uint8_t b1, b2;
-+
-+ for (i = 0; i < seg->length; i++) {
-+ b1 = tcp_opt_hdr[i];
-+ b2 = tcp_opt_hdr[i + 1];
-+
-+ if (b1 == 0x00)
-+ break;
-+
-+ /* test for MSS */
-+ if (!MSS && (b1 == 0x02 && b2 == 0x04)) {
-+ changes->field_offset_changes[0] = (i + 2) * CHAR_BIT;
-+ MSS = 1;
-+ }
-+
-+ /* test for WS --- yet buggy somehow */
-+ if (!WS && (b1 == 0x03 && b2 == 0x03)) {
-+ changes->field_offset_changes[1] = (i + 2) * CHAR_BIT;
-+ WS = 1;
-+ }
-+
-+ /* test for SACK*/
-+ if (!SACK && (b1 == 0x04 && b2 == 0x02)) {
-+ changes->field_offset_changes[2] = i * CHAR_BIT; /* has no value */
-+ SACK = 1;
-+ }
-+
-+ /* test for TS */
-+ if (!TS && (b1 == 0x08 && b2 == 0x0A)) {
-+ changes->field_offset_changes[3] = (i + 2) * CHAR_BIT;
-+ changes->field_offset_changes[4] = (i + 2 + 4) * CHAR_BIT;
-+ TS = 1;
-+ }
-+ }
-+
-+ return changes;
-+
-+}
-+
-+void luaopen_protbuf_tcp(lua_State *L)
-+{
-+ register_protbuf(L, (struct protocol_buf *)&tcp_protocol_buf, PACKET_TCP);
-+}
-+void luaopen_protbuf_tcp_options(lua_State *L)
-+{
-+ register_protbuf(L, (struct protocol_buf *)&tcp_options_and_data_buf, PACKET_TCP_OPTIONS);
-+}
-+
-+
---- /dev/null
-+++ b/extensions/LUA/prot_buf_tftp.c
-@@ -0,0 +1,87 @@
-+/*
-+ * Copyright (C) 2010 University of Basel
-+ * by Andre Graf
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, see .
-+ */
-+#include "controller.h"
-+
-+static const struct protocol_field tftp_protocol_fields[] = {
-+ /* field name offset length getter setter */
-+ { "opcode", 0, 16, get_16_bit_generic, NULL},
-+ { "filename", 0, 0, get_string_generic, NULL},
-+ { "mode", 0, 0, get_string_generic, NULL},
-+ { "block_nr", 0, 16, get_16_bit_generic, NULL},
-+ { "data", 0, 0, NULL, NULL},
-+ PROT_FIELD_SENTINEL,
-+};
-+
-+struct field_changes * tftp_get_field_changes(lua_State *L, lua_packet_segment * seg)
-+{
-+ /* depending on the value stored inside the 'opcode'-field we have to change
-+ * offsets and lengths */
-+ uint8_t *tftp_hdr = seg->start + seg->offset;
-+ short opcode = ntohs(*((uint16_t *)tftp_hdr));
-+ /* get an allocated 'field_changes' structure */
-+ struct field_changes * changes = get_allocated_field_changes(L, 5);
-+ switch (opcode) {
-+ case 1: /* Read Request (RRQ) */
-+ /* setting offset and length of field 'filename' */
-+ changes->field_offset_changes[1] = sizeof(unsigned short) << 3;
-+ changes->field_length_changes[1] = strlen((char *)tftp_hdr + sizeof(unsigned short)) << 3;
-+ /* setting offset and length of field 'mode' */
-+ changes->field_offset_changes[2] = changes->field_offset_changes[1] + changes->field_length_changes[1];
-+ changes->field_length_changes[2] = strlen((char *)tftp_hdr + (changes->field_offset_changes[2] >> 3));
-+ break;
-+ case 2: /* Write Request (WRQ) */
-+ /* setting offset and length of field 'filename' */
-+ changes->field_offset_changes[1] = sizeof(unsigned short) << 3;
-+ changes->field_length_changes[1] = strlen((char *)tftp_hdr + sizeof(unsigned short)) << 3;
-+ /* setting offset and length of field 'mode' */
-+ changes->field_offset_changes[2] = changes->field_offset_changes[1] + changes->field_length_changes[1];
-+ changes->field_length_changes[2] = strlen((char *)tftp_hdr + (changes->field_offset_changes[2] >> 3));
-+ break;
-+ case 3: /* Data (DATA) */
-+ /* setting offset of field 'block_nr' */
-+ changes->field_offset_changes[3] = sizeof(unsigned short) << 3;
-+ /* setting offset of field 'data' */
-+ changes->field_offset_changes[4] = changes->field_offset_changes[3] + (sizeof(unsigned short) << 3);
-+ break;
-+ case 4: /* Acknowledgment (ACK) */
-+ /* setting offset of field 'block_nr' */
-+ changes->field_offset_changes[3] = sizeof(unsigned short) << 3;
-+ break;
-+ case 5: /* Error (ERROR) */
-+ /* we don't care ... yet */
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ return changes;
-+}
-+
-+static const struct protocol_buf tftp_protocol_buf = {
-+ .is_dynamic = 0,
-+ .name = LUA_PACKET_SEG_TFTP,
-+ .payload_field = NULL,
-+ .protocol_fields = (struct protocol_field *)&tftp_protocol_fields,
-+ .has_protocol = NULL, /* we don't need it, since we don't provide a payload field */
-+ .get_field_changes = tftp_get_field_changes,
-+};
-+
-+void luaopen_protbuf_tftp(lua_State *L)
-+{
-+ register_protbuf(L, (struct protocol_buf *)&tftp_protocol_buf, PACKET_TFTP);
-+}
---- /dev/null
-+++ b/extensions/LUA/prot_buf_udp.c
-@@ -0,0 +1,53 @@
-+/*
-+ * Copyright (C) 2010 University of Basel
-+ * by Andre Graf
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, see .
-+ */
-+
-+#if defined(__KERNEL__)
-+ #include
-+#endif
-+
-+#include "controller.h"
-+
-+
-+static int32_t udp_has_protocol(lua_State *L, struct protocol_buf * prot_buf, lua_packet_segment * seg, int32_t protocol_type)
-+{
-+ return 1;
-+}
-+
-+static const struct protocol_field udp_protocol_fields[] = {
-+ /* field name offset length getter setter */
-+ { "sport", 0, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "dport", 16, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "length", 32, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "check", 48, 16, get_16_bit_generic, set_16_bit_generic },
-+ { "data", 64, 0, NULL, NULL },
-+ PROT_FIELD_SENTINEL,
-+};
-+
-+static const struct protocol_buf udp_protocol_buf = {
-+ .is_dynamic = 0,
-+ .name = LUA_PACKET_SEG_UDP,
-+ .payload_field = "data",
-+ .protocol_fields = (struct protocol_field *)&udp_protocol_fields,
-+ .has_protocol = &udp_has_protocol,
-+ .get_field_changes = NULL,
-+};
-+
-+void luaopen_protbuf_udp(lua_State *L)
-+{
-+ register_protbuf(L, (struct protocol_buf *)&udp_protocol_buf, PACKET_UDP);
-+}
---- /dev/null
-+++ b/extensions/LUA/xt_LUA.h
-@@ -0,0 +1,36 @@
-+/*
-+ * Copyright (C) 2010 University of Basel
-+ * by Andre Graf
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, see .
-+ */
-+
-+#ifndef XT_LUA_H_
-+#define XT_LUA_H_
-+
-+#define MAX_FILENAME_SIZE 256
-+#define MAX_FUNCTION_SIZE 256
-+#define MAX_SCRIPT_SIZE 32768
-+#define LUA_STATE_ARRAY_SIZE 128
-+
-+/* the targetsize is stored in a u16, so max size of the xt_lua_tginfo cannot exceed 64K*/
-+struct xt_lua_tginfo {
-+ char buf[MAX_SCRIPT_SIZE];
-+ char filename[MAX_FILENAME_SIZE];
-+ char function[MAX_FUNCTION_SIZE];
-+ __u64 script_size;
-+ __u32 state_id;
-+};
-+
-+#endif /* XT_LUA_H_ */
---- /dev/null
-+++ b/extensions/LUA/xt_LUA_target.c
-@@ -0,0 +1,286 @@
-+/*
-+ * Copyright (C) 2010 University of Basel
-+ * by Andre Graf
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, see .
-+ */
-+
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include
-+#include "xt_LUA.h"
-+
-+#include "controller.h"
-+
-+/*::*
-+ * lua_envs
-+ * ----------
-+ * This array holds a defined number of `lua_envs`_ structures.
-+ * The used array index is also used as the Lua state identifier.
-+ * The size of the array is defined in `LUA_STATE_ARRAY_SIZE`_.
-+ */
-+struct lua_env * lua_envs[LUA_STATE_ARRAY_SIZE];
-+
-+/*::*
-+ * lua_state_refs
-+ * --------------
-+ * This array holds the reference counts of the several `lua_nf_state`_s
-+ * which are stored inside the array `lua_states`_.
-+ */
-+uint32_t lua_state_refs[LUA_STATE_ARRAY_SIZE] = { 0 };
-+
-+/*::*
-+ * lua_tg
-+ * ------
-+ * This function is called whenever a packet matches all matching conditions
-+ * inside a rule. It is the target. It extracts the state identifier comming
-+ * inside the *xt_target_param* structure and uses it to access the proper
-+ * Lua state inside the `lua_states`_ array.
-+ *
-+ * It then constructs a new Lua userdata of type *lua_packet_segment* and
-+ * initializes it with the lowest network header available. This userdata
-+ * is annotated with the Lua metatable `LUA_PACKET_SEG_RAW`_ which converts
-+ * the userdata to a raw lua packet having all raw functions available.
-+ * This raw packet is the single parameter to the Lua function *process_packet*
-+ * which must be defined inside the Lua script provided by the user. So far
-+ * hardcoded, may be later configured by Lua - subject to change.
-+ *
-+ * The process_packet function must return an integer value, the verdict. For
-+ * convenience reasons xt_LUA exports the verdicts NF_ACCEPT, NF_DROP and
-+ * XT_CONTINUE inside the *register_lua_packet_lib* function.
-+ */
-+
-+spinlock_t lock = SPIN_LOCK_UNLOCKED;
-+
-+static uint32_t
-+lua_tg(struct sk_buff *pskb, const struct xt_target_param *par)
-+{
-+ uint32_t verdict;
-+ lua_packet_segment *p;
-+ const struct xt_lua_tginfo *info = par->targinfo;
-+ lua_State * L;
-+
-+ /* START critical section on SMP, PacketScript is on the sequential trail at the moment TODO*/
-+ spin_lock_irq(&lock);
-+
-+ L = lua_envs[info->state_id]->L;
-+
-+ if (!skb_ensure_writable(pskb, pskb->len))
-+ return NF_DROP;
-+
-+ /* call the function provided by --function parameter or the default 'process_packet' defined in Lua */
-+ lua_getglobal(L, info->function);
-+
-+ /* push the lua_packet_segment as a parameter */
-+ p = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
-+ if (pskb->mac_header)
-+ p->start = pskb->mac_header;
-+ else if (pskb->network_header)
-+ p->start = pskb->network_header;
-+ else if (pskb->transport_header)
-+ p->start = pskb->transport_header;
-+ p->offset = 0;
-+ p->length = (unsigned long)pskb->tail - (unsigned long)p->start;
-+ p->changes = NULL;
-+
-+ /* marking userdata 'lua_packet_seg' with the corresponding metatable */
-+ luaL_getmetatable(L, LUA_PACKET_SEG_RAW);
-+ lua_setmetatable(L, -2);
-+
-+ /* push a reference to the skb as a parameter, needed at the moment for calculating TCP checksum, but I am not happy with it*/
-+ lua_pushlightuserdata(L, (void *)skb_get(pskb));
-+
-+ /* do the function call (2 argument, 1 result) */
-+ if (lua_pcall(L, 2, 1, 0) != 0) {
-+ printk(KERN_ERR "LUA [%d]: pcall '%s' failed: %s\n", info->state_id, info->function, lua_tostring(L, -1));
-+ lua_pop(L, 1);
-+ return NF_DROP;
-+ }
-+
-+ if (!lua_isnumber(L, -1)) {
-+ printk(KERN_ERR "LUA [%d]: function '%s' must return a verdict\n", info->state_id, info->function);
-+ lua_pop(L, 1);
-+ return NF_DROP;
-+ }
-+
-+ verdict = lua_tonumber(L, -1);
-+ lua_pop(L, 1);
-+
-+ kfree_skb(pskb);
-+
-+ /* END critical section on SMP */
-+ spin_unlock_irq(&lock);
-+
-+
-+ return verdict;
-+
-+}
-+/* Helper for checkentry */
-+static bool load_script_into_state(uint32_t state_id, unsigned long script_size, char *script_buf)
-+{
-+ char *buf = kmalloc(script_size, GFP_KERNEL);
-+ int32_t ret;
-+ struct lua_env * env = kmalloc(sizeof(struct lua_env), GFP_KERNEL);
-+
-+ if (!(script_size > 0)) {
-+ pr_debug("LUA [%d]: script_size %lu < 0\n", state_id, script_size);
-+ return false;
-+ }
-+
-+ env->L = lua_open();
-+ luaopen_base(env->L);
-+ luaopen_controller(env->L);
-+
-+ lua_getglobal(env->L, "_G");
-+ lua_pushinteger(env->L, state_id);
-+ lua_setfield(env->L, -2, "STATE_ID");
-+ lua_pop(env->L, 1); /* pop _G */
-+
-+ strncpy(buf, script_buf, script_size);
-+ ret = luaL_loadbuffer(env->L, buf, script_size, "PacketScript, loadbuffer") ||
-+ lua_pcall(env->L, 0, 1, 0);
-+
-+ if (ret != 0) {
-+ printk(KERN_ERR "LUA [%d]: failure loading script, error %s \n", state_id, lua_tostring(env->L, -1));
-+ lua_pop(env->L, 1);
-+ kfree(buf);
-+ kfree(env);
-+ return false;
-+ }
-+
-+ lua_envs[state_id] = env;
-+
-+ kfree(buf);
-+
-+ return true;
-+}
-+/*::*
-+ * lua_tg_checkentry
-+ * -----------------
-+ * This function is used as a kernel-side sanity check of the data comming
-+ * from the iptables userspace program. Since this is the function which is
-+ * called everytime a new rule (with -j xt_LUA) is injected, this function
-+ * is used to do the bookkeeping work, such as counting the reference of
-+ * several Lua states and the initialization of new states if needed. As an
-+ * extra initialization step it loads the provided Lua script into the Lua
-+ * state.
-+ *
-+ * Lua state initialization
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~
-+ * 1. If a new rule is inserted and there is no existing state for the given
-+ * state identifier (default state identifier is 0) a new Lua state is
-+ * initialized using *lua_open*.
-+ * 2. The Lua base library is registered inside the newly initialized state.
-+ * Have a look at *lua/lbaselib.c* to see what functions of the Lua base
-+ * library are available inside Lua.
-+ * 3. The Lua packet library is registered inside the Lua state using the
-+ * function *register_lua_packet_lib*. So far this function only registers
-+ * the Netfilter verdicts NF_ACCEPT, NF_DROP and XT_CONTINUE inside the
-+ * global environment of the given Lua state.
-+ * 4. All the protocol Buffers, and the functions for accessing the bytes are
-+ * registered using *register_protocols*.
-+ *
-+ * Lua state reference counting
-+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-+ * Bookkeeping of the Lua states inside the *lua_state_refs* array. The
-+ * state identifier is mapped to the array index, which holds an integer
-+ * counting the several initialized states.
-+ *
-+ * Loading the Lua script
-+ * ~~~~~~~~~~~~~~~~~~~~~~
-+ * Copying the buffer which was initialized by the userspace program to a
-+ * buffer with the proper size. The script is then loaded by the function
-+ * xt_LUA_loadcode, which wrapps the *luaL_loadbuffer* function and does
-+ * some workqueue initialization. So far this is done each time this function
-+ * is called, subject to change.
-+ */
-+static bool
-+lua_tg_checkentry(const struct xt_tgchk_param *par)
-+{
-+ const struct xt_lua_tginfo *info = par->targinfo;
-+
-+ if (load_script_into_state(info->state_id, info->script_size, (char *)info->buf)) {
-+ lua_state_refs[info->state_id]++;
-+ return true;
-+ }
-+ return false;
-+}
-+
-+/*::*
-+ * lua_tg_destroy
-+ * --------------
-+ * This function is the counterpart of the `lua_tg_checkentry`_ function. It is
-+ * responsible to free all the resources alocated inside the checkentry process.
-+ * To be more specific it frees the Lua state using *lua_close* and kfree on all
-+ * the dynamically allocated pointers to the registered dynamic protocol buffers.
-+ *
-+ * Additionally the function cares about decrementing the reference counters
-+ * inside the array `lua_states`_.
-+ */
-+static void
-+lua_tg_destroy(const struct xt_tgdtor_param *par)
-+{
-+ const struct xt_lua_tginfo *info = par->targinfo;
-+ struct lua_env * env = lua_envs[info->state_id];
-+
-+ if (lua_state_refs[info->state_id] == 1) {
-+ lua_close(env->L);
-+ cleanup_dynamic_prot_bufs(); /* clean memory allocated by protocols defined in Lua */
-+ kfree(env);
-+ pr_debug("LUA [%d]: Rule removed, close Lua state\n", info->state_id);
-+ } else
-+ pr_debug("LUA [%d]: Rule removed, Lua state stays open, referenced %d time(s)\n",
-+ info->state_id, lua_state_refs[info->state_id] - 1);
-+
-+ lua_state_refs[info->state_id]--;
-+}
-+
-+static struct xt_target lua_tg_reg __read_mostly = {
-+ .name = "LUA",
-+ .revision = 0,
-+ .family = NFPROTO_UNSPEC,
-+ .targetsize = XT_ALIGN(sizeof(struct xt_lua_tginfo)),
-+ .target = lua_tg,
-+ .checkentry = lua_tg_checkentry,
-+ .destroy = lua_tg_destroy,
-+ .me = THIS_MODULE,
-+};
-+
-+
-+static int32_t lua_tg_init(void)
-+{
-+ return xt_register_target(&lua_tg_reg);
-+}
-+
-+static void lua_tg_exit(void)
-+{
-+ xt_unregister_target(&lua_tg_reg);
-+}
-+
-+module_init(lua_tg_init);
-+module_exit(lua_tg_exit);
-+
-+MODULE_AUTHOR("Andre Graf ");
-+MODULE_DESCRIPTION("Xtables: Processing of matched packets using the Lua scripting environment");
-+MODULE_ALIAS("ipt_LUA");
-+MODULE_ALIAS("ipt6t_LUA");
-+MODULE_ALIAS("arpt_LUA");
-+MODULE_ALIAS("ebt_LUA");
-+MODULE_LICENSE("GPL");
-+
-+
-+
---- a/extensions/Kbuild
-+++ b/extensions/Kbuild
-@@ -27,6 +27,7 @@ obj-${build_pknock} += pknock/
- obj-${build_psd} += xt_psd.o
- obj-${build_quota2} += xt_quota2.o
- obj-${build_rtsp} += rtsp/
-+obj-${build_LUA} += LUA/
-
- -include ${M}/*.Kbuild
- -include ${M}/Kbuild.*
---- a/extensions/Mbuild
-+++ b/extensions/Mbuild
-@@ -22,3 +22,4 @@ obj-${build_pknock} += pknock/
- obj-${build_psd} += libxt_psd.so
- obj-${build_quota2} += libxt_quota2.so
- obj-${build_gradm} += libxt_gradm.so
-+obj-${build_LUA} += LUA/
---- a/mconfig
-+++ b/mconfig
-@@ -23,3 +23,4 @@ build_pknock=m
- build_psd=m
- build_quota2=m
- build_rtsp=m
-+build_LUA=m
diff --git a/xtables-addons/patches/201-fix-lua-packetscript.patch b/xtables-addons/patches/201-fix-lua-packetscript.patch
deleted file mode 100755
index a9fb796d0..000000000
--- a/xtables-addons/patches/201-fix-lua-packetscript.patch
+++ /dev/null
@@ -1,127 +0,0 @@
---- a/extensions/LUA/xt_LUA_target.c
-+++ b/extensions/LUA/xt_LUA_target.c
-@@ -19,7 +19,7 @@
- #include
- #include
- #include
--#include
-+#include
- #include
- #include
- #include "xt_LUA.h"
-@@ -64,10 +64,10 @@ uint32_t lua_state_refs[LUA_STATE_ARRAY
- * XT_CONTINUE inside the *register_lua_packet_lib* function.
- */
-
--spinlock_t lock = SPIN_LOCK_UNLOCKED;
-+DEFINE_SPINLOCK(lock);
-
- static uint32_t
--lua_tg(struct sk_buff *pskb, const struct xt_target_param *par)
-+lua_tg(struct sk_buff *pskb, const struct xt_action_param *par)
- {
- uint32_t verdict;
- lua_packet_segment *p;
-@@ -88,11 +88,11 @@ lua_tg(struct sk_buff *pskb, const struc
- /* push the lua_packet_segment as a parameter */
- p = (lua_packet_segment *)lua_newuserdata(L, sizeof(lua_packet_segment));
- if (pskb->mac_header)
-- p->start = pskb->mac_header;
-+ p->start = skb_mac_header(pskb);
- else if (pskb->network_header)
-- p->start = pskb->network_header;
-+ p->start = skb_network_header(pskb);
- else if (pskb->transport_header)
-- p->start = pskb->transport_header;
-+ p->start = skb_transport_header(pskb);
- p->offset = 0;
- p->length = (unsigned long)pskb->tail - (unsigned long)p->start;
- p->changes = NULL;
-@@ -208,16 +208,16 @@ static bool load_script_into_state(uint3
- * some workqueue initialization. So far this is done each time this function
- * is called, subject to change.
- */
--static bool
-+static int
- lua_tg_checkentry(const struct xt_tgchk_param *par)
- {
- const struct xt_lua_tginfo *info = par->targinfo;
-
- if (load_script_into_state(info->state_id, info->script_size, (char *)info->buf)) {
- lua_state_refs[info->state_id]++;
-- return true;
-+ return 0;
- }
-- return false;
-+ return -EINVAL;
- }
-
- /*::*
---- a/extensions/LUA/lua/llimits.h
-+++ b/extensions/LUA/lua/llimits.h
-@@ -8,7 +8,6 @@
- #define llimits_h
-
- #include
--#include
-
- #include "lua.h"
-
---- a/extensions/LUA/lua/lapi.c
-+++ b/extensions/LUA/lua/lapi.c
-@@ -4,9 +4,6 @@
- ** See Copyright Notice in lua.h
- */
-
--#include
--#include
--#include
- #include
-
- #define lapi_c
---- a/extensions/LUA/lua/ltable.c
-+++ b/extensions/LUA/lua/ltable.c
-@@ -18,7 +18,6 @@
- ** Hence even when the load factor reaches 100%, performance remains good.
- */
-
--#include
- #include
-
- #define ltable_c
---- a/extensions/LUA/lua/luaconf.h
-+++ b/extensions/LUA/lua/luaconf.h
-@@ -13,8 +13,12 @@
- #if !defined(__KERNEL__)
- #include
- #else
-+#include
-+
-+#undef UCHAR_MAX
-+#undef BUFSIZ
-+#undef NO_FPU
- #define UCHAR_MAX 255
--#define SHRT_MAX 32767
- #define BUFSIZ 8192
- #define NO_FPU
- #endif
-@@ -637,6 +641,8 @@ union luai_Cast { double l_d; long l_l;
- */
- #if defined(__KERNEL__)
- #undef LUA_USE_ULONGJMP
-+#define setjmp __builtin_setjmp
-+#define longjmp __builtin_longjmp
- #endif
-
- #if defined(__cplusplus)
---- a/extensions/LUA/lua/llex.h
-+++ b/extensions/LUA/lua/llex.h
-@@ -10,6 +10,8 @@
- #include "lobject.h"
- #include "lzio.h"
-
-+/* prevent conflict with definition from asm/current.h */
-+#undef current
-
- #define FIRST_RESERVED 257
-
diff --git a/xtables-addons/patches/202-fix-lua-packetscript-kernel-5.16-no-isystem.patch b/xtables-addons/patches/202-fix-lua-packetscript-kernel-5.16-no-isystem.patch
deleted file mode 100755
index 5279619da..000000000
--- a/xtables-addons/patches/202-fix-lua-packetscript-kernel-5.16-no-isystem.patch
+++ /dev/null
@@ -1,284 +0,0 @@
-Linux 5.16 includes 04e85bbf71c9 ("isystem: delete global -isystem compile option")
-
-compile error on >=5.16
-xtables-addons-3.21/extensions/LUA/lua/lua.h:12:10: fatal error: stdarg.h: No such file or directory
- 12 | #include
- | ^~~~~~~~~~
-
-Generated with coccinelle:
-
-cat <cocci-xtables-lua-linux-5.16.spatch
-@include_arg@
-@@
- #include
-
-@include_def@
-@@
- #include
-
-@include_both depends on include_arg && include_def@
-@@
- #include
-
-@add_include_linux_stdheaders_both depends on include_both@
-@@
-+#include
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)
-?#include
-?#include