~ubuntu-branches/debian/sid/freeciv/sid

« back to all changes in this revision

Viewing changes to dependencies/toluaxx/src/lib/tolua_map.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams, Karl Goetz, Clint Adams
  • Date: 2010-02-23 22:09:02 UTC
  • mfrom: (7.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100223220902-s3spqi1x4e190y0t
[ Karl Goetz ]
* Remove civserver files in /etc/ggzd/ (Closes: 523772, 517787)
* Adding ${misc:Depends} to all binary packages (lintian warnings)

[ Clint Adams ]
* New upstream version.
  - Drop data_dsc_use_bindir.diff (binary pathnames have changed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* tolua: functions to map features
 
2
** Support code for Lua bindings.
 
3
** Written by Waldemar Celes
 
4
** TeCGraf/PUC-Rio
 
5
** Apr 2003
 
6
** $Id: tolua_map.c 14589 2008-04-15 21:40:53Z cazfi $
 
7
*/
 
8
 
 
9
/* This code is free software; you can redistribute it and/or modify it.
 
10
** The software provided hereunder is on an "as is" basis, and
 
11
** the author has no obligation to provide maintenance, support, updates,
 
12
** enhancements, or modifications.
 
13
*/
 
14
 
 
15
#include "toluaxx.h"
 
16
#include "tolua_event.h"
 
17
#include "lauxlib.h"
 
18
 
 
19
#include <string.h>
 
20
#include <stdio.h>
 
21
#include <stdlib.h>
 
22
#include <math.h>
 
23
 
 
24
 
 
25
static lua_State* __tolua_current_state_=NULL;
 
26
 
 
27
/* Call method to self object from C
 
28
 */
 
29
/*
 
30
  TOLUA_API int tolua_callmethod(lua_State* L,void* self,const char* type,const char* func,int nargs,int nresults){
 
31
  tolua_pushusertype(L,self,type);
 
32
  lua_pushstring(L,func);
 
33
  lua_gettable(L,-2);
 
34
  if(!lua_isfunction(L,-1)){lua_pop(L,1);return 0;} * method is nil *
 
35
  lua_insert(L,-2-nargs);
 
36
  lua_insert(L,-1-nargs);
 
37
  lua_call(L,nargs+1,nresults);
 
38
  return 1;
 
39
  }*/
 
40
 
 
41
TOLUA_API lua_State* tolua_state(){ /* Get current state  */
 
42
  return __tolua_current_state_;
 
43
}
 
44
TOLUA_API void tolua_setstate(lua_State* L){ /* Set current state */
 
45
  __tolua_current_state_=L;
 
46
}
 
47
 
 
48
/* Create metatable
 
49
 * Create and register new metatable
 
50
 */
 
51
static int tolua_newmetatable (lua_State* L, char* name){
 
52
  int r = luaL_newmetatable(L,name);
 
53
  
 
54
#ifdef LUA_VERSION_NUM /* only lua 5.1 */
 
55
  if (r) {
 
56
    lua_pushvalue(L, -1);
 
57
    lua_pushstring(L, name);
 
58
    lua_settable(L, LUA_REGISTRYINDEX); /* reg[mt] = type_name */
 
59
  };
 
60
#endif
 
61
  
 
62
  if (r) tolua_classevents(L); /* set meta events */
 
63
  lua_pop(L,1);
 
64
  return r;
 
65
}
 
66
 
 
67
/* Map super classes
 
68
 * It sets 'name' as being also a 'base', mapping all super classes of 'base' in 'name'
 
69
 */
 
70
static void mapsuper (lua_State* L, const char* name, const char* base) {
 
71
  /* push registry.super */
 
72
  lua_pushstring(L,"tolua_super");
 
73
  lua_rawget(L,LUA_REGISTRYINDEX);    /* stack: super */
 
74
  luaL_getmetatable(L,name);          /* stack: super mt */
 
75
  lua_rawget(L,-2);                   /* stack: super table */
 
76
  if (lua_isnil(L,-1)) {
 
77
    /* create table */
 
78
    lua_pop(L,1);
 
79
    lua_newtable(L);                    /* stack: super table */
 
80
    luaL_getmetatable(L,name);          /* stack: super table mt */
 
81
    lua_pushvalue(L,-2);                /* stack: super table mt table */
 
82
    lua_rawset(L,-4);                   /* stack: super table */
 
83
  }
 
84
  
 
85
  /* set base as super class */
 
86
  lua_pushstring(L,base);
 
87
  lua_pushboolean(L,1);
 
88
  lua_rawset(L,-3);                    /* stack: super table */
 
89
  
 
90
  /* set all super class of base as super class of name */
 
91
  luaL_getmetatable(L,base);          /* stack: super table base_mt */
 
92
  lua_rawget(L,-3);                   /* stack: super table base_table */
 
93
  if (lua_istable(L,-1)) {
 
94
    /* traverse base table */
 
95
    lua_pushnil(L);  /* first key */
 
96
    while (lua_next(L,-2) != 0) {
 
97
      /* stack: ... base_table key value */
 
98
      lua_pushvalue(L,-2);    /* stack: ... base_table key value key */
 
99
      lua_insert(L,-2);       /* stack: ... base_table key key value */
 
100
      lua_rawset(L,-5);       /* stack: ... base_table key */
 
101
    }
 
102
  }
 
103
  lua_pop(L,3);                       /* stack: <empty> */
 
104
}
 
105
 
 
106
/* creates a 'tolua_ubox' table for base clases, and
 
107
// expects the metatable and base metatable on the stack */
 
108
static void set_ubox(lua_State* L) {
 
109
  /* mt basemt */
 
110
  if (!lua_isnil(L, -1)) {
 
111
    lua_pushstring(L, "tolua_ubox");
 
112
    lua_rawget(L,-2);
 
113
  } else {
 
114
    lua_pushnil(L);
 
115
  }
 
116
  /* mt basemt base_ubox */
 
117
  if (!lua_isnil(L,-1)) {
 
118
    lua_pushstring(L, "tolua_ubox");
 
119
    lua_insert(L, -2);
 
120
    /* mt basemt key ubox */
 
121
    lua_rawset(L,-4);
 
122
    /* (mt with ubox) basemt */
 
123
  } else {
 
124
    /* mt basemt nil */
 
125
    lua_pop(L, 1);
 
126
    lua_pushstring(L,"tolua_ubox"); lua_newtable(L);
 
127
    /* make weak value metatable for ubox table to allow userdata to be
 
128
       garbage-collected */
 
129
    lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3);               /* stack: string ubox mt */
 
130
    lua_setmetatable(L, -2);  /* stack:mt basemt string ubox */
 
131
    lua_rawset(L,-4);
 
132
  }
 
133
}
 
134
 
 
135
/* Map inheritance
 
136
 * It sets 'name' as derived from 'base' by setting 'base' as metatable of 'name'
 
137
 */
 
138
static void mapinheritance (lua_State* L, const char* name, const char* base){
 
139
  /* set metatable inheritance */
 
140
  luaL_getmetatable(L,name);
 
141
  
 
142
  if (base && *base) luaL_getmetatable(L,base); else {
 
143
    
 
144
    if (lua_getmetatable(L, -1)) { /* already has a mt, we don't overwrite it */
 
145
      lua_pop(L, 2);
 
146
      return;
 
147
    }
 
148
    luaL_getmetatable(L,"tolua_commonclass");
 
149
  }
 
150
  
 
151
  set_ubox(L);
 
152
  
 
153
  lua_setmetatable(L,-2);
 
154
  lua_pop(L,1);
 
155
}
 
156
 
 
157
/* Object type
 
158
 */
 
159
static int tolua_bnd_type (lua_State* L){
 
160
  tolua_typename(L,lua_gettop(L));
 
161
  return 1;
 
162
}
 
163
 
 
164
/* Take ownership
 
165
 */
 
166
static int tolua_bnd_takeownership (lua_State* L){
 
167
  int success = 0;
 
168
  if (lua_isuserdata(L,1)) {
 
169
    if (lua_getmetatable(L,1)) {       /* if metatable? */
 
170
      lua_pop(L,1);             /* clear metatable off stack */
 
171
      /* force garbage collection to avoid C to reuse a to-be-collected address */
 
172
#ifdef LUA_VERSION_NUM
 
173
      lua_gc(L, LUA_GCCOLLECT, 0);
 
174
#else
 
175
      lua_setgcthreshold(L,0);
 
176
#endif
 
177
      success = tolua_register_gc(L,1);
 
178
    }
 
179
  }
 
180
  lua_pushboolean(L,success!=0);
 
181
  return 1;
 
182
}
 
183
 
 
184
/* Release ownership
 
185
 */
 
186
static int tolua_bnd_releaseownership (lua_State* L){
 
187
  int done = 0;
 
188
  if (lua_isuserdata(L,1)) {
 
189
    void* u = *((void**)lua_touserdata(L,1));
 
190
    /* force garbage collection to avoid releasing a to-be-collected address */
 
191
#ifdef LUA_VERSION_NUM
 
192
    lua_gc(L, LUA_GCCOLLECT, 0);
 
193
#else
 
194
    lua_setgcthreshold(L,0);
 
195
#endif
 
196
    lua_pushstring(L,"tolua_gc");
 
197
    lua_rawget(L,LUA_REGISTRYINDEX);
 
198
    lua_pushlightuserdata(L,u);
 
199
    lua_rawget(L,-2);
 
200
    lua_getmetatable(L,1);
 
201
    if (lua_rawequal(L,-1,-2)) {  /* check that we are releasing the correct type */
 
202
      lua_pushlightuserdata(L,u);
 
203
      lua_pushnil(L);
 
204
      lua_rawset(L,-5);
 
205
      done = 1;
 
206
    }
 
207
  }
 
208
  lua_pushboolean(L,done!=0);
 
209
  return 1;
 
210
}
 
211
 
 
212
/* Type casting
 
213
 */
 
214
static int tolua_bnd_cast (lua_State* L){
 
215
  
 
216
  /* // old code
 
217
     void* v = tolua_tousertype(L,1,NULL);
 
218
     const char* s = tolua_tostring(L,2,NULL);
 
219
     if (v && s)
 
220
     tolua_pushusertype(L,v,s);
 
221
     else
 
222
     lua_pushnil(L);
 
223
     return 1;
 
224
  */
 
225
  
 
226
  void* v;
 
227
  const char* s;
 
228
  if (lua_islightuserdata(L, 1)) {
 
229
    v = tolua_touserdata(L, 1, NULL);
 
230
  } else {
 
231
    v = tolua_tousertype(L, 1, 0);
 
232
  }
 
233
  
 
234
  s = tolua_tostring(L,2,NULL);
 
235
  if (v && s) tolua_pushusertype(L,v,s);
 
236
  else lua_pushnil(L);
 
237
  return 1;
 
238
}
 
239
 
 
240
/* Inheritance
 
241
 */
 
242
static int tolua_bnd_inherit (lua_State* L) {
 
243
 
 
244
  /* stack: lua object, c object */
 
245
  lua_pushstring(L, ".c_instance");
 
246
  lua_pushvalue(L, -2);
 
247
  lua_rawset(L, -4);
 
248
  /* l_obj[".c_instance"] = c_obj */
 
249
 
 
250
  return 0;
 
251
}
 
252
 
 
253
#ifdef LUA_VERSION_NUM /* lua 5.1 */
 
254
static int tolua_bnd_setpeer(lua_State* L) {
 
255
  /* stack: userdata, table */
 
256
  if (!lua_isuserdata(L, -2)) {
 
257
    lua_pushstring(L, "Invalid argument #1 to setpeer: userdata expected.");
 
258
    lua_error(L);
 
259
  }
 
260
  
 
261
  if (lua_isnil(L, -1)) {
 
262
    lua_pop(L, 1);
 
263
    lua_pushvalue(L, TOLUA_NOPEER);
 
264
  }
 
265
  lua_setfenv(L, -2);
 
266
  
 
267
  return 0;
 
268
}
 
269
 
 
270
static int tolua_bnd_getpeer(lua_State* L) {
 
271
  /* stack: userdata */
 
272
  lua_getfenv(L, -1);
 
273
  if (lua_rawequal(L, -1, TOLUA_NOPEER)) {
 
274
    lua_pop(L, 1);
 
275
    lua_pushnil(L);
 
276
  }
 
277
  return 1;
 
278
}
 
279
#endif
 
280
 
 
281
/*
 
282
 *  toluaxx proxy technique
 
283
 *  
 
284
 *
 
285
 */
 
286
 
 
287
TOLUA_API void tolua_proxystack(lua_State* L){
 
288
  /* stack: */
 
289
  lua_pushstring(L,"tolua_proxy");  /* stack: "tolua_proxy" */
 
290
  lua_rawget(L,LUA_REGISTRYINDEX);  /* stack: ?proxy_stack_table? */
 
291
  if(!lua_istable(L,-1)){  /* check if ?proxy_stack_table? is not table */
 
292
    lua_remove(L,-1);               /* stack: */
 
293
    lua_pushnil(L);                 /* stack: nil */
 
294
    return;
 
295
  }
 
296
  /* stack: proxy_stack_table */
 
297
}
 
298
 
 
299
TOLUA_API int tolua_proxytop(lua_State* L){
 
300
  int __tolua_proxy_top_;
 
301
  int __top_;
 
302
  __top_=lua_gettop(L);              /* stack: */
 
303
  lua_pushstring(L,"tolua_proxy");   /* stack: "tolua_proxy" */
 
304
  lua_rawget(L,LUA_REGISTRYINDEX);   /* stack: ?proxy_stack_table? */
 
305
  if(lua_istable(L,-1)){    /* check if ?proxy_stack_table? is table */
 
306
    lua_pushnumber(L,0);             /* stack: proxy_stack_table 0 */
 
307
    lua_rawget(L,-2);                /* stack: proxy_stack_table ?proxy_stack_top? */
 
308
    if(lua_isnumber(L,-1)){ /* check if ?proxy_stack_top? is number */
 
309
      __tolua_proxy_top_=lua_tonumber(L,-1);
 
310
    }else __tolua_proxy_top_=-2;
 
311
  }else __tolua_proxy_top_=-1;
 
312
  lua_settop(L,__top_);
 
313
  return __tolua_proxy_top_;
 
314
}
 
315
 
 
316
TOLUA_API int tolua_proxypush(lua_State* L){
 
317
  int __tolua_proxy_top_;
 
318
  
 
319
  /* get proxy stack table */           /* stack: */
 
320
  lua_pushstring(L,"tolua_proxy");      /* stack: "tolua_proxy" */
 
321
  lua_rawget(L,LUA_REGISTRYINDEX);      /* stack: ?proxy_stack_table? */
 
322
  if(!lua_istable(L,-1)){  /* check if ?proxy_stack_table? is not table */
 
323
    lua_remove(L,-1);                   /* stack: */
 
324
    return 0;
 
325
  }
 
326
 
 
327
  /* get stack level top counter */     /* stack: proxy_stack_table */
 
328
  lua_pushnumber(L,0);                  /* stack: proxy_stack_table 0 */
 
329
  lua_rawget(L,-2);                     /* stack: proxy_stack_table ?proxy_stack_top? */
 
330
  if(!lua_isnumber(L,-1)){ /* check if ?proxy_stack_top? is not number */
 
331
    lua_remove(L,-1);                   /* stack: proxy_stack_table */
 
332
    lua_remove(L,-1);                   /* stack: */
 
333
    return 0;
 
334
  }
 
335
  __tolua_proxy_top_=lua_tonumber(L,-1);
 
336
  lua_remove(L,-1);                     /* stack: proxy_stack_table */
 
337
 
 
338
  /* decrement stack level top counter */
 
339
  __tolua_proxy_top_=__tolua_proxy_top_+1;
 
340
  lua_pushnumber(L,0);                  /* stack: proxy_stack_table 0 */
 
341
  lua_pushnumber(L,__tolua_proxy_top_); /* stack: proxy_stack_table 0 new_proxy_stack_top */
 
342
  lua_rawset(L,-3);                     /* stack: proxy_stack_table */
 
343
  
 
344
  /* create a new proxy stack level */
 
345
  lua_pushnumber(L,__tolua_proxy_top_); /* stack: proxy_stack_table new_proxy_stack_top */
 
346
  lua_newtable(L);                      /* stack: proxy_stack_table new_proxy_stack_level */
 
347
  lua_rawset(L,-3);                     /* stack: proxy_stack_table */
 
348
  
 
349
  /* clear lua stack */
 
350
  lua_remove(L,-1);                     /* stack: */
 
351
  return 1;
 
352
}
 
353
 
 
354
TOLUA_API int tolua_proxypop(lua_State* L){
 
355
  int __tolua_proxy_top_;
 
356
  
 
357
  /* get proxy stack table */           /* stack: */
 
358
  lua_pushstring(L,"tolua_proxy");      /* stack: "tolua_proxy" */
 
359
  lua_rawget(L,LUA_REGISTRYINDEX);      /* stack: ?proxy_stack_table? */
 
360
  if(!lua_istable(L,-1)){  /* check if ?proxy_stack_table? is not table */
 
361
    lua_remove(L,-1);                   /* stack: */
 
362
    return 0;
 
363
  }
 
364
  
 
365
  /* get stack level top counter */     /* stack: proxy_stack_table */
 
366
  lua_pushnumber(L,0);                  /* stack: proxy_stack_table 0 */
 
367
  lua_rawget(L,-2);                     /* stack: proxy_stack_table ?proxy_stack_top? */
 
368
  if(!lua_isnumber(L,-1)){ /* check if ?proxy_stack_top? is not number */
 
369
    lua_remove(L,-1);                   /* stack: proxy_stack_table */
 
370
    lua_remove(L,-1);                   /* stack: */
 
371
    return 0;
 
372
  }
 
373
  __tolua_proxy_top_=lua_tonumber(L,-1);
 
374
  lua_remove(L,-1);                     /* stack: proxy_stack_table */
 
375
  if(__tolua_proxy_top_<1){ /* check if proxy top counter is smaller one */
 
376
    lua_remove(L,-1);                   /* stack: */
 
377
    return 0;
 
378
  }
 
379
  /* remove proxy stack level */
 
380
  lua_pushnumber(L,__tolua_proxy_top_); /* stack: proxy_stack_table proxy_stack_top */
 
381
  lua_pushnil(L);                       /* stack: proxy_stack_table  */
 
382
  lua_rawset(L,-3);                     /* stack: proxy_stack_table */
 
383
  
 
384
  /* decrement stack level top counter */
 
385
  __tolua_proxy_top_=__tolua_proxy_top_-1;
 
386
  lua_pushnumber(L,0);                  /* stack: proxy_stack_table 0 */
 
387
  lua_pushnumber(L,__tolua_proxy_top_); /* stack: proxy_stack_table 0 new_proxy_stack_top */
 
388
  lua_rawset(L,-3);                     /* stack: proxy_stack_table */
 
389
  
 
390
  /* clear lua stack */
 
391
  lua_remove(L,-1);                     /* stack: */
 
392
  return 1;
 
393
}
 
394
 
 
395
TOLUA_API void tolua_proxylevel(lua_State* L, int level){
 
396
  /* stack: */
 
397
  int __tolua_proxy_top_=tolua_proxytop(L);
 
398
  if( level>+__tolua_proxy_top_ ||
 
399
      level<-__tolua_proxy_top_ ||
 
400
      level==0 ){ /* check if level exceded */
 
401
    lua_pushnil(L);                 /* stack: nil */
 
402
    return;
 
403
  }                                 /* stack: */
 
404
  lua_pushstring(L,"tolua_proxy");  /* stack: "tolua_proxy" */
 
405
  lua_rawget(L,LUA_REGISTRYINDEX);  /* stack: ?proxy_stack_table? */
 
406
  if(!lua_istable(L,-1)){  /* check if ?proxy_stack_table? is not table */
 
407
    lua_remove(L,-1);               /* stack: */
 
408
    lua_pushnil(L);                 /* stack: nil */
 
409
    return;
 
410
  }
 
411
  /* stack: proxy_stack_table */
 
412
  level=level>0?level:__tolua_proxy_top_+level+1;
 
413
  lua_pushnumber(L,level);          /* stack: proxy_stack_table proxy_stack_level */
 
414
  lua_rawget(L,-2);                 /* stack: proxy_stack_table ?proxy_level_table? */
 
415
  lua_remove(L,-2);                 /* stack: ?proxy_level_table? */
 
416
  if(!lua_istable(L,-1)){  /* check if ?proxy_level_table? is not table */
 
417
    lua_remove(L,-1);               /* stack: */
 
418
    lua_pushnil(L);                 /* stack: nil */
 
419
    return;
 
420
  }
 
421
  return;                           /* stack: proxy_level_table */
 
422
}
 
423
 
 
424
TOLUA_API void tolua_getproxy(lua_State* L, int level){
 
425
  /* stack: key */
 
426
  tolua_proxylevel(L,level);        /* stack: key ?proxy_level_table? */
 
427
  if(!lua_istable(L,-1)){  /* check if ?proxy_level_table? is not table */
 
428
    lua_remove(L,-1);               /* stack: key */
 
429
    lua_remove(L,-1);               /* stack: */
 
430
    lua_pushnil(L);                 /* stack: nil */
 
431
    return;
 
432
  }                                 /* stack: key proxy_level_table */
 
433
  lua_insert(L,-2);                 /* stack: proxy_level_table key */
 
434
  lua_rawget(L,-2);                 /* stack: proxy_level_table value */
 
435
  lua_remove(L,-2);                 /* stack: value */
 
436
  return;
 
437
}
 
438
 
 
439
TOLUA_API void tolua_setproxy(lua_State* L, int level){
 
440
  /* stack: key val */
 
441
  tolua_proxylevel(L,level);        /* stack: key val ?proxy_level_table? */
 
442
  if(!lua_istable(L,-1)){  /* check if ?proxy_level_table? is not table */
 
443
    lua_remove(L,-1);               /* stack: key val */
 
444
    lua_remove(L,-1);               /* stack: key */
 
445
    lua_remove(L,-1);               /* stack: */
 
446
    return;
 
447
  }                                 /* stack: key val proxy_level_table */
 
448
  lua_insert(L,-3);                 /* stack: proxy_level_table key val */
 
449
  lua_rawset(L,-3);                 /* stack: proxy_level_table */
 
450
  lua_remove(L,-2);                 /* stack: */
 
451
  return;
 
452
}
 
453
 
 
454
/* local state = tolua.proxy.push() */
 
455
static int tolua_bnd_proxy_push(lua_State* L){
 
456
  int __ret_code_;
 
457
  __ret_code_=tolua_proxypush(L);
 
458
  lua_pushboolean(L,__ret_code_);
 
459
  return 1;
 
460
}
 
461
 
 
462
/* local state = tolua.proxy.pop() */
 
463
static int tolua_bnd_proxy_pop(lua_State* L){
 
464
  int __ret_code_;
 
465
  __ret_code_=tolua_proxypop(L);
 
466
  lua_pushboolean(L,__ret_code_);
 
467
  return 1;
 
468
}
 
469
 
 
470
/* local level_table = tolua.proxy.level(<level>) */
 
471
static int tolua_bnd_proxy_level(lua_State* L){
 
472
  /* stack: <level> */
 
473
  int __proxy_level_=TOLUA_PROXY_TOP;
 
474
  if(lua_isnumber(L,1)){ /* check if level has been retrieved */
 
475
    /* stack: level */
 
476
    __proxy_level_=lua_tonumber(L,1);
 
477
    lua_remove(L,1);                 /* stack: */
 
478
  }                                  /* stack: */
 
479
  tolua_proxylevel(L,__proxy_level_);
 
480
  return 1;
 
481
}
 
482
 
 
483
/* local val = tolua.proxy.get(key<,level>) */
 
484
static int tolua_bnd_proxy_get(lua_State* L){
 
485
  /* stack: key <level> */
 
486
  int __proxy_level_=TOLUA_PROXY_TOP;
 
487
  if(lua_gettop(L)<1 || lua_isnil(L,1)){  /* check if key hasn't been retrieved */
 
488
    lua_pushnil(L);
 
489
    return 1;
 
490
  }
 
491
  if(lua_isnumber(L,2)){ /* check if level has been retrieved */
 
492
    /* stack: key level */
 
493
    __proxy_level_=lua_tonumber(L,2);
 
494
    lua_remove(L,2);                 /* stack: key */
 
495
  }                                  /* stack: key */
 
496
  tolua_getproxy(L,__proxy_level_);  /* stack: val */
 
497
  return 1;
 
498
}
 
499
 
 
500
/* tolua.proxy.set(key,value<,level>) */
 
501
static int tolua_bnd_proxy_set(lua_State* L){
 
502
  /* stack: key val <level> */
 
503
  int __proxy_level_=TOLUA_PROXY_TOP;
 
504
  if(lua_gettop(L)<1 || lua_isnil(L,1)){  /* check if key hasn't been retrieved */
 
505
    return 0;
 
506
  }
 
507
  if(lua_gettop(L)<2){  /* check if val hasn't been retrieved */
 
508
    return 0;
 
509
  }
 
510
  if(lua_isnumber(L,3)){ /* check if level has been retrieved */
 
511
    /* stack: key val level */
 
512
    __proxy_level_=lua_tonumber(L,3);
 
513
    lua_remove(L,3);                 /* stack: key val */
 
514
  }                                  /* stack: key val */
 
515
  tolua_setproxy(L,__proxy_level_);  /* stack: */
 
516
  return 0;
 
517
}
 
518
 
 
519
/* local top = tolua.proxy.top() */
 
520
static int tolua_bnd_proxy_top(lua_State* L){
 
521
  int __top_=tolua_proxytop(L);
 
522
  lua_pushnumber(L,__top_);
 
523
  return 1;
 
524
}
 
525
 
 
526
/* static int class_gc_event (lua_State* L); */
 
527
 
 
528
TOLUA_API void tolua_open (lua_State* L){
 
529
  int top = lua_gettop(L);
 
530
  lua_pushstring(L,"tolua_opened");
 
531
  lua_rawget(L,LUA_REGISTRYINDEX);
 
532
  if (!lua_isboolean(L,-1)){
 
533
    lua_pushstring(L,"tolua_opened"); lua_pushboolean(L,1); lua_rawset(L,LUA_REGISTRYINDEX);
 
534
    
 
535
#ifndef LUA_VERSION_NUM /* only prior to lua 5.1 */
 
536
    /* create peer object table */
 
537
    lua_pushstring(L, "tolua_peers"); lua_newtable(L);
 
538
    /* make weak key metatable for peers indexed by userdata object */
 
539
    lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "k"); lua_rawset(L, -3);                /* stack: string peers mt */
 
540
    lua_setmetatable(L, -2);   /* stack: string peers */
 
541
    lua_rawset(L,LUA_REGISTRYINDEX);
 
542
#endif
 
543
    
 
544
    /* create object ptr -> udata mapping table */
 
545
    lua_pushstring(L,"tolua_ubox"); lua_newtable(L);
 
546
    /* make weak value metatable for ubox table to allow userdata to be
 
547
       garbage-collected */
 
548
    lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3);
 
549
    /* stack: string ubox mt */
 
550
    lua_setmetatable(L, -2);  /* stack: string ubox */
 
551
    lua_rawset(L,LUA_REGISTRYINDEX);
 
552
    
 
553
    lua_pushstring(L,"tolua_super"); lua_newtable(L); lua_rawset(L,LUA_REGISTRYINDEX);
 
554
    lua_pushstring(L,"tolua_gc");    lua_newtable(L); lua_rawset(L,LUA_REGISTRYINDEX);
 
555
    lua_pushstring(L,"tolua_node");  lua_newtable(L); lua_rawset(L,LUA_REGISTRYINDEX);
 
556
    
 
557
    /* create proxy table */
 
558
    lua_pushstring(L,"tolua_proxy");
 
559
    lua_newtable(L);
 
560
    /* insert counter into proxy table */
 
561
    lua_pushnumber(L,0);
 
562
    lua_pushnumber(L,0);
 
563
    lua_rawset(L,-3);
 
564
    /* register proxy table */
 
565
    lua_rawset(L,LUA_REGISTRYINDEX);
 
566
    
 
567
    /* create gc_event closure */
 
568
    lua_pushstring(L, "tolua_gc_event");
 
569
    lua_pushstring(L, "tolua_gc");
 
570
    lua_rawget(L, LUA_REGISTRYINDEX);
 
571
    lua_pushstring(L, "tolua_super");
 
572
    lua_rawget(L, LUA_REGISTRYINDEX);
 
573
    lua_pushcclosure(L, class_gc_event, 2);
 
574
    lua_rawset(L, LUA_REGISTRYINDEX);
 
575
    
 
576
    tolua_newmetatable(L,"tolua_commonclass");
 
577
    
 
578
    tolua_module(L,NULL,0);
 
579
    tolua_beginmodule(L,NULL);
 
580
    tolua_module(L,"tolua",0);
 
581
    tolua_beginmodule(L,"tolua");
 
582
    tolua_function(L,"type",tolua_bnd_type);
 
583
    tolua_function(L,"takeownership",tolua_bnd_takeownership);
 
584
    tolua_function(L,"releaseownership",tolua_bnd_releaseownership);
 
585
    tolua_function(L,"cast",tolua_bnd_cast);
 
586
    tolua_function(L,"inherit", tolua_bnd_inherit);
 
587
#ifdef LUA_VERSION_NUM /* lua 5.1 */
 
588
    tolua_function(L,"setpeer", tolua_bnd_setpeer);
 
589
    tolua_function(L,"getpeer", tolua_bnd_getpeer);
 
590
#endif
 
591
    
 
592
    tolua_module(L,"proxy",0);
 
593
    tolua_beginmodule(L,"proxy");
 
594
    tolua_function(L,"top",  tolua_bnd_proxy_top);
 
595
    tolua_function(L,"push", tolua_bnd_proxy_push);
 
596
    tolua_function(L,"pop",  tolua_bnd_proxy_pop);
 
597
    tolua_function(L,"set",  tolua_bnd_proxy_set);
 
598
    tolua_function(L,"get",  tolua_bnd_proxy_get);
 
599
    tolua_function(L,"level",tolua_bnd_proxy_level);
 
600
    tolua_endmodule(L);
 
601
    
 
602
    tolua_endmodule(L);
 
603
    tolua_endmodule(L);
 
604
  }
 
605
  lua_settop(L,top);
 
606
  tolua_setstate(L);
 
607
}
 
608
 
 
609
/* Copy a C object
 
610
 */
 
611
TOLUA_API void* tolua_copy (lua_State* L, void* value, unsigned int size){
 
612
  void* clone = (void*)malloc(size);
 
613
  if (clone) memcpy(clone,value,size);
 
614
  else tolua_error(L,"insuficient memory",NULL);
 
615
  return clone;
 
616
}
 
617
 
 
618
/* Default collect function
 
619
 */
 
620
TOLUA_API int tolua_default_collect (lua_State* tolua_S){
 
621
  void* self = tolua_tousertype(tolua_S,1,0);
 
622
  free(self);
 
623
  return 0;
 
624
}
 
625
 
 
626
/* Do clone
 
627
 */
 
628
TOLUA_API int tolua_register_gc (lua_State* L, int lo){
 
629
  int success = 1;
 
630
  void *value = *(void **)lua_touserdata(L,lo);
 
631
  lua_pushstring(L,"tolua_gc");
 
632
  lua_rawget(L,LUA_REGISTRYINDEX);
 
633
  lua_pushlightuserdata(L,value);
 
634
  lua_rawget(L,-2);
 
635
  if (!lua_isnil(L,-1)){ /* make sure that object is not already owned */
 
636
    success = 0;
 
637
  } else {
 
638
    lua_pushlightuserdata(L,value);
 
639
    lua_getmetatable(L,lo);
 
640
    lua_rawset(L,-4);
 
641
  }
 
642
  lua_pop(L,2);
 
643
  return success;
 
644
}
 
645
 
 
646
/* Register a usertype
 
647
 * It creates the correspoding metatable in the registry, for both 'type' and 'const type'.
 
648
 * It maps 'const type' as being also a 'type'
 
649
 */
 
650
TOLUA_API void tolua_usertype (lua_State* L, char* type)
 
651
{
 
652
  char ctype[128] = "const ";
 
653
  strncat(ctype,type,120);
 
654
 
 
655
  /* create both metatables */
 
656
  if (tolua_newmetatable(L,ctype) && tolua_newmetatable(L,type))
 
657
    mapsuper(L,type,ctype);             /* 'type' is also a 'const type' */
 
658
}
 
659
 
 
660
 
 
661
/* Begin module
 
662
 * It pushes the module (or class) table on the stack
 
663
 */
 
664
TOLUA_API void tolua_beginmodule (lua_State* L, char* name)
 
665
{
 
666
  if (name)
 
667
    {
 
668
      lua_pushstring(L,name);
 
669
      lua_rawget(L,-2);
 
670
    }
 
671
  else
 
672
    lua_pushvalue(L,LUA_GLOBALSINDEX);
 
673
}
 
674
 
 
675
/* End module
 
676
 * It pops the module (or class) from the stack
 
677
 */
 
678
TOLUA_API void tolua_endmodule (lua_State* L)
 
679
{
 
680
  lua_pop(L,1);
 
681
}
 
682
 
 
683
/* Map module
 
684
 * It creates a new module
 
685
 */
 
686
#if 1
 
687
TOLUA_API void tolua_module (lua_State* L, char* name, int hasvar)
 
688
{
 
689
  if (name)
 
690
    {
 
691
      /* tolua module */
 
692
      lua_pushstring(L,name);
 
693
      lua_rawget(L,-2);
 
694
      if (!lua_istable(L,-1))  /* check if module already exists */
 
695
        {
 
696
          lua_pop(L,1);
 
697
          lua_newtable(L);
 
698
          lua_pushstring(L,name);
 
699
          lua_pushvalue(L,-2);
 
700
          lua_rawset(L,-4);       /* assing module into module */
 
701
        }
 
702
    }
 
703
  else
 
704
    {
 
705
      /* global table */
 
706
      lua_pushvalue(L,LUA_GLOBALSINDEX);
 
707
    }
 
708
  if (hasvar)
 
709
    {
 
710
      if (!tolua_ismodulemetatable(L))  /* check if it already has a module metatable */
 
711
        {
 
712
          /* create metatable to get/set C/C++ variable */
 
713
          lua_newtable(L);
 
714
          tolua_moduleevents(L);
 
715
          if (lua_getmetatable(L,-2))
 
716
            lua_setmetatable(L,-2);  /* set old metatable as metatable of metatable */
 
717
          lua_setmetatable(L,-2);
 
718
        }
 
719
    }
 
720
  lua_pop(L,1);               /* pop module */
 
721
}
 
722
#else
 
723
TOLUA_API void tolua_module (lua_State* L, char* name, int hasvar)
 
724
{
 
725
  if (name)
 
726
    {
 
727
      /* tolua module */
 
728
      lua_pushstring(L,name);
 
729
      lua_newtable(L);
 
730
    }
 
731
  else
 
732
    {
 
733
      /* global table */
 
734
      lua_pushvalue(L,LUA_GLOBALSINDEX);
 
735
    }
 
736
  if (hasvar)
 
737
    {
 
738
      /* create metatable to get/set C/C++ variable */
 
739
      lua_newtable(L);
 
740
      tolua_moduleevents(L);
 
741
      if (lua_getmetatable(L,-2))
 
742
        lua_setmetatable(L,-2);  /* set old metatable as metatable of metatable */
 
743
      lua_setmetatable(L,-2);
 
744
    }
 
745
  if (name)
 
746
    lua_rawset(L,-3);       /* assing module into module */
 
747
  else
 
748
    lua_pop(L,1);           /* pop global table */
 
749
}
 
750
#endif
 
751
 
 
752
static void push_collector(lua_State* L, const char* type, lua_CFunction col) {
 
753
 
 
754
  /* push collector function, but only if it's not NULL, or if there's no
 
755
     collector already */
 
756
  if (!col) return;
 
757
  luaL_getmetatable(L,type);
 
758
  lua_pushstring(L,".collector");
 
759
  /*
 
760
    if (!col) {
 
761
    lua_pushvalue(L, -1);
 
762
    lua_rawget(L, -3);
 
763
    if (!lua_isnil(L, -1)) {
 
764
    lua_pop(L, 3);
 
765
    return;
 
766
    };
 
767
    lua_pop(L, 1);
 
768
    };
 
769
    //  */
 
770
  lua_pushcfunction(L,col);
 
771
 
 
772
  lua_rawset(L,-3);
 
773
  lua_pop(L, 1);
 
774
};
 
775
 
 
776
/* Map C class
 
777
 * It maps a C class, setting the appropriate inheritance and super classes.
 
778
 */
 
779
TOLUA_API void tolua_cclass (lua_State* L, char* lname, char* name, char* base, lua_CFunction col)
 
780
{
 
781
  char cname[128] = "const ";
 
782
  char cbase[128] = "const ";
 
783
  strncat(cname,name,120);
 
784
  strncat(cbase,base,120);
 
785
 
 
786
  mapinheritance(L,name,base);
 
787
  mapinheritance(L,cname,name);
 
788
 
 
789
  mapsuper(L,cname,cbase);
 
790
  mapsuper(L,name,base);
 
791
 
 
792
  lua_pushstring(L,lname);
 
793
        
 
794
  push_collector(L, name, col);
 
795
  /*
 
796
    luaL_getmetatable(L,name);
 
797
    lua_pushstring(L,".collector");
 
798
    lua_pushcfunction(L,col);
 
799
 
 
800
    lua_rawset(L,-3);
 
801
  */
 
802
        
 
803
  luaL_getmetatable(L,name);
 
804
  lua_rawset(L,-3);              /* assign class metatable to module */
 
805
 
 
806
  /* now we also need to store the collector table for the const
 
807
     instances of the class */
 
808
  push_collector(L, cname, col);
 
809
  /*
 
810
    luaL_getmetatable(L,cname);
 
811
    lua_pushstring(L,".collector");
 
812
    lua_pushcfunction(L,col);
 
813
    lua_rawset(L,-3);
 
814
    lua_pop(L,1);
 
815
  */
 
816
        
 
817
 
 
818
}
 
819
 
 
820
/* Add base
 
821
 * It adds additional base classes to a class (for multiple inheritance)
 
822
 * (not for now)
 
823
 TOLUA_API void tolua_addbase(lua_State* L, char* name, char* base) {
 
824
 
 
825
 char cname[128] = "const ";
 
826
 char cbase[128] = "const ";
 
827
 strncat(cname,name,120);
 
828
 strncat(cbase,base,120);
 
829
 
 
830
 mapsuper(L,cname,cbase);
 
831
 mapsuper(L,name,base);
 
832
 };
 
833
*/
 
834
 
 
835
/* Map function
 
836
 * It assigns a function into the current module (or class)
 
837
 */
 
838
TOLUA_API void tolua_function (lua_State* L, char* name, lua_CFunction func){
 
839
  lua_pushstring(L,name);
 
840
  lua_pushcfunction(L,func);
 
841
  lua_rawset(L,-3);
 
842
}
 
843
 
 
844
/* sets the __call event for the class (expects the class' main table on top) */
 
845
/*      never really worked :(
 
846
        TOLUA_API void tolua_set_call_event(lua_State* L, lua_CFunction func, char* type) {
 
847
 
 
848
        lua_getmetatable(L, -1);
 
849
        //luaL_getmetatable(L, type);
 
850
        lua_pushstring(L,"__call");
 
851
        lua_pushcfunction(L,func);
 
852
        lua_rawset(L,-3);
 
853
        lua_pop(L, 1);
 
854
        };
 
855
*/
 
856
 
 
857
/* Map constant number
 
858
 * It assigns a constant number into the current module (or class)
 
859
 */
 
860
TOLUA_API void tolua_constant (lua_State* L, char* name, double value){
 
861
  lua_pushstring(L,name);
 
862
  tolua_pushnumber(L,value);
 
863
  lua_rawset(L,-3);
 
864
}
 
865
 
 
866
 
 
867
/* Map variable
 
868
 * It assigns a variable into the current module (or class)
 
869
 */
 
870
TOLUA_API void tolua_variable (lua_State* L, char* name, lua_CFunction get, lua_CFunction set){
 
871
  /* get func */
 
872
  lua_pushstring(L,".get");
 
873
  lua_rawget(L,-2);
 
874
  if (!lua_istable(L,-1)) {
 
875
    /* create .get table, leaving it at the top */
 
876
    lua_pop(L,1);
 
877
    lua_newtable(L);
 
878
    lua_pushstring(L,".get");
 
879
    lua_pushvalue(L,-2);
 
880
    lua_rawset(L,-4);
 
881
  }
 
882
  lua_pushstring(L,name);
 
883
  lua_pushcfunction(L,get);
 
884
  lua_rawset(L,-3);                  /* store variable */
 
885
  lua_pop(L,1);                      /* pop .get table */
 
886
  
 
887
  /* set func */
 
888
  if (set) {
 
889
    lua_pushstring(L,".set");
 
890
    lua_rawget(L,-2);
 
891
    if (!lua_istable(L,-1)) {
 
892
      /* create .set table, leaving it at the top */
 
893
      lua_pop(L,1);
 
894
      lua_newtable(L);
 
895
      lua_pushstring(L,".set");
 
896
      lua_pushvalue(L,-2);
 
897
      lua_rawset(L,-4);
 
898
    }
 
899
    lua_pushstring(L,name);
 
900
    lua_pushcfunction(L,set);
 
901
    lua_rawset(L,-3);                  /* store variable */
 
902
    lua_pop(L,1);                      /* pop .set table */
 
903
  }
 
904
}
 
905
 
 
906
/* Access const array
 
907
 * It reports an error when trying to write into a const array
 
908
 */
 
909
static int const_array (lua_State* L){
 
910
  luaL_error(L,"value of const array cannot be changed");
 
911
  return 0;
 
912
}
 
913
 
 
914
/* Map an array
 
915
 * It assigns an array into the current module (or class)
 
916
 */
 
917
TOLUA_API void tolua_array (lua_State* L, char* name, lua_CFunction get, lua_CFunction set){
 
918
  lua_pushstring(L,".get");
 
919
  lua_rawget(L,-2);
 
920
  if (!lua_istable(L,-1)) {
 
921
    /* create .get table, leaving it at the top */
 
922
    lua_pop(L,1);
 
923
    lua_newtable(L);
 
924
    lua_pushstring(L,".get");
 
925
    lua_pushvalue(L,-2);
 
926
    lua_rawset(L,-4);
 
927
  }
 
928
  lua_pushstring(L,name);
 
929
  
 
930
  lua_newtable(L);           /* create array metatable */
 
931
  lua_pushvalue(L,-1);
 
932
  lua_setmetatable(L,-2);    /* set the own table as metatable (for modules) */
 
933
  lua_pushstring(L,"__index");
 
934
  lua_pushcfunction(L,get);
 
935
  lua_rawset(L,-3);
 
936
  lua_pushstring(L,"__newindex");
 
937
  lua_pushcfunction(L,set?set:const_array);
 
938
  lua_rawset(L,-3);
 
939
  
 
940
  lua_rawset(L,-3);                  /* store variable */
 
941
  lua_pop(L,1);                      /* pop .get table */
 
942
}
 
943
 
 
944
 
 
945
TOLUA_API void tolua_dobuffer(lua_State* L, char* B, unsigned int size, const char* name) {
 
946
#ifdef LUA_VERSION_NUM /* lua 5.1 */
 
947
  if (! luaL_loadbuffer(L, B, size, name)) {
 
948
    lua_pcall(L, 0, 0, 0);
 
949
  }
 
950
#else
 
951
  lua_dobuffer(L, B, size, name);
 
952
#endif
 
953
};
 
954