Tizen 2.0 Release
[external/tolua++.git] / tolua_push.c
1 /* tolua: functions to push C values.
2 ** Support code for Lua bindings.
3 ** Written by Waldemar Celes
4 ** TeCGraf/PUC-Rio
5 ** Apr 2003
6 ** $Id: $
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 "tolua++.h"
16 #include "lauxlib.h"
17
18 #include <stdlib.h>
19
20 TOLUA_API void tolua_pushvalue (lua_State* L, int lo)
21 {
22  lua_pushvalue(L,lo);
23 }
24
25 TOLUA_API void tolua_pushboolean (lua_State* L, int value)
26 {
27  lua_pushboolean(L,value);
28 }
29
30 TOLUA_API void tolua_pushnumber (lua_State* L, lua_Number value)
31 {
32  lua_pushnumber(L,value);
33 }
34
35 TOLUA_API void tolua_pushstring (lua_State* L, const char* value)
36 {
37  if (value == NULL)
38   lua_pushnil(L);
39  else
40   lua_pushstring(L,value);
41 }
42
43 TOLUA_API void tolua_pushuserdata (lua_State* L, void* value)
44 {
45  if (value == NULL)
46   lua_pushnil(L);
47  else
48   lua_pushlightuserdata(L,value);
49 }
50
51 TOLUA_API void tolua_pushusertype (lua_State* L, void* value, const char* type)
52 {
53  if (value == NULL)
54   lua_pushnil(L);
55  else
56  {
57   luaL_getmetatable(L, type);
58   lua_pushstring(L,"tolua_ubox");
59   lua_rawget(L,-2);        /* stack: mt ubox */
60   if (lua_isnil(L, -1)) {
61           lua_pop(L, 1);
62           lua_pushstring(L, "tolua_ubox");
63           lua_rawget(L, LUA_REGISTRYINDEX);
64   };
65   lua_pushlightuserdata(L,value);
66   lua_rawget(L,-2);                       /* stack: mt ubox ubox[u] */
67   if (lua_isnil(L,-1))
68   {
69    lua_pop(L,1);                          /* stack: mt ubox */
70    lua_pushlightuserdata(L,value);
71    *(void**)lua_newuserdata(L,sizeof(void *)) = value;   /* stack: mt ubox u newud */
72    lua_pushvalue(L,-1);                   /* stack: mt ubox u newud newud */
73    lua_insert(L,-4);                      /* stack: mt newud ubox u newud */
74    lua_rawset(L,-3);                      /* stack: mt newud ubox */
75    lua_pop(L,1);                          /* stack: mt newud */
76    /*luaL_getmetatable(L,type);*/
77    lua_pushvalue(L, -2);                        /* stack: mt newud mt */
78    lua_setmetatable(L,-2);                      /* stack: mt newud */
79
80    #ifdef LUA_VERSION_NUM
81    lua_pushvalue(L, TOLUA_NOPEER);
82    lua_setfenv(L, -2);
83    #endif
84   }
85   else
86   {
87    /* check the need of updating the metatable to a more specialized class */
88    lua_insert(L,-2);                       /* stack: mt ubox[u] ubox */
89    lua_pop(L,1);                           /* stack: mt ubox[u] */
90    lua_pushstring(L,"tolua_super");
91    lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: mt ubox[u] super */
92    lua_getmetatable(L,-2);                 /* stack: mt ubox[u] super mt */
93    lua_rawget(L,-2);                       /* stack: mt ubox[u] super super[mt] */
94                         if (lua_istable(L,-1))
95                         {
96                                 lua_pushstring(L,type);                 /* stack: mt ubox[u] super super[mt] type */
97                                 lua_rawget(L,-2);                       /* stack: mt ubox[u] super super[mt] flag */
98                                 if (lua_toboolean(L,-1) == 1)   /* if true */
99                                 {
100                                         lua_pop(L,3);   /* mt ubox[u]*/
101                                         lua_remove(L, -2);
102                                         return;
103                                 }
104                         }
105                         /* type represents a more specilized type */
106                         /*luaL_getmetatable(L,type);             // stack: mt ubox[u] super super[mt] flag mt */
107                         lua_pushvalue(L, -5);                                   /* stack: mt ubox[u] super super[mt] flag mt */
108                         lua_setmetatable(L,-5);                /* stack: mt ubox[u] super super[mt] flag */
109                         lua_pop(L,3);                          /* stack: mt ubox[u] */
110   }
111   lua_remove(L, -2);    /* stack: ubox[u]*/
112  }
113 }
114
115 TOLUA_API void tolua_pushusertype_and_takeownership (lua_State* L, void* value, const char* type)
116 {
117         tolua_pushusertype(L,value,type);
118         tolua_register_gc(L,lua_gettop(L));
119 }
120
121 TOLUA_API void tolua_pushfieldvalue (lua_State* L, int lo, int index, int v)
122 {
123  lua_pushnumber(L,index);
124  lua_pushvalue(L,v);
125  lua_settable(L,lo);
126 }
127
128 TOLUA_API void tolua_pushfieldboolean (lua_State* L, int lo, int index, int v)
129 {
130  lua_pushnumber(L,index);
131  lua_pushboolean(L,v);
132  lua_settable(L,lo);
133 }
134
135
136 TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, lua_Number v)
137 {
138  lua_pushnumber(L,index);
139  tolua_pushnumber(L,v);
140  lua_settable(L,lo);
141 }
142
143 TOLUA_API void tolua_pushfieldstring (lua_State* L, int lo, int index, const char* v)
144 {
145  lua_pushnumber(L,index);
146  tolua_pushstring(L,v);
147  lua_settable(L,lo);
148 }
149
150 TOLUA_API void tolua_pushfielduserdata (lua_State* L, int lo, int index, void* v)
151 {
152  lua_pushnumber(L,index);
153  tolua_pushuserdata(L,v);
154  lua_settable(L,lo);
155 }
156
157 TOLUA_API void tolua_pushfieldusertype (lua_State* L, int lo, int index, void* v, const char* type)
158 {
159  lua_pushnumber(L,index);
160  tolua_pushusertype(L,v,type);
161  lua_settable(L,lo);
162 }
163
164 TOLUA_API void tolua_pushfieldusertype_and_takeownership (lua_State* L, int lo, int index, void* v, const char* type)
165 {
166  lua_pushnumber(L,index);
167  tolua_pushusertype(L,v,type);
168         tolua_register_gc(L,lua_gettop(L));
169  lua_settable(L,lo);
170 }
171