Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/pch/src/tolua/tolua_is.c @ 3127

Last change on this file since 3127 was 3127, checked in by rgrieder, 15 years ago

Update to tolua 1.0.93

  • Property svn:eol-style set to native
File size: 12.1 KB
Line 
1/* tolua: functions to check types.
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#include <string.h>
20
21/* a fast check if a is b, without parameter validation
22 i.e. if b is equal to a or a superclass of a. */
23TOLUA_API int tolua_fast_isa(lua_State *L, int mt_indexa, int mt_indexb, int super_index)
24{
25 int result;
26        if (lua_rawequal(L,mt_indexa,mt_indexb))
27                result = 1;
28        else
29        {
30                if (super_index) {
31                        lua_pushvalue(L, super_index);
32                } else {
33                        lua_pushliteral(L,"tolua_super");
34                        lua_rawget(L,LUA_REGISTRYINDEX);  /* stack: super */
35                };
36                lua_pushvalue(L,mt_indexa);       /* stack: super mta */
37                lua_rawget(L,-2);                 /* stack: super super[mta] */
38                lua_pushvalue(L,mt_indexb);       /* stack: super super[mta] mtb */
39                lua_rawget(L,LUA_REGISTRYINDEX);  /* stack: super super[mta] typenameB */
40                lua_rawget(L,-2);                 /* stack: super super[mta] bool */
41                result = lua_toboolean(L,-1);
42                lua_pop(L,3);
43        }
44        return result;
45}
46
47/* Push and returns the corresponding object typename */
48TOLUA_API const char* tolua_typename (lua_State* L, int lo)
49{
50        int tag = lua_type(L,lo);
51 if (tag == LUA_TNONE)
52  lua_pushstring(L,"[no object]");
53 else if (tag != LUA_TUSERDATA && tag != LUA_TTABLE)
54  lua_pushstring(L,lua_typename(L,tag));
55 else if (tag == LUA_TUSERDATA)
56 {
57  if (!lua_getmetatable(L,lo))
58   lua_pushstring(L,lua_typename(L,tag));
59                else
60                {
61                 lua_rawget(L,LUA_REGISTRYINDEX);
62                 if (!lua_isstring(L,-1))
63                        {
64                  lua_pop(L,1);
65                                lua_pushstring(L,"[undefined]");
66                        }
67                }
68        }
69        else  /* is table */
70        {
71                lua_pushvalue(L,lo);
72                lua_rawget(L,LUA_REGISTRYINDEX);
73                if (!lua_isstring(L,-1))
74                {
75                        lua_pop(L,1);
76                        lua_pushstring(L,"table");
77                }
78                else
79                {
80   lua_pushstring(L,"class ");
81                        lua_insert(L,-2);
82                        lua_concat(L,2);
83                }
84        }
85        return lua_tostring(L,-1);
86}
87
88TOLUA_API void tolua_error (lua_State* L, const char* msg, tolua_Error* err)
89{
90        if (msg[0] == '#')
91        {
92  const char* expected = err->type;
93                const char* provided = tolua_typename(L,err->index);
94  if (msg[1]=='f')
95  {
96   int narg = err->index;
97                        if (err->array)
98    luaL_error(L,"%s\n     argument #%d is array of '%s'; array of '%s' expected.\n",
99               msg+2,narg,provided,expected);
100                        else
101    luaL_error(L,"%s\n     argument #%d is '%s'; '%s' expected.\n",
102               msg+2,narg,provided,expected);
103  }
104  else if (msg[1]=='v')
105                {
106                        if (err->array)
107    luaL_error(L,"%s\n     value is array of '%s'; array of '%s' expected.\n",
108               msg+2,provided,expected);
109                        else
110    luaL_error(L,"%s\n     value is '%s'; '%s' expected.\n",
111               msg+2,provided,expected);
112                }
113 }
114 else
115  luaL_error(L,msg);
116}
117
118/* the equivalent of lua_is* for usertable */
119static  int lua_isusertable (lua_State* L, int lo, const const char* type)
120{
121        int r = 0;
122        if (lo < 0) lo = lua_gettop(L)+lo+1;
123        lua_pushvalue(L,lo);
124        lua_rawget(L,LUA_REGISTRYINDEX);  /* get registry[t] */
125        if (lua_isstring(L,-1))
126        {
127                r = strcmp(lua_tostring(L,-1),type)==0;
128                if (!r)
129                {
130                        /* try const */
131                        lua_pushstring(L,"const ");
132                        lua_insert(L,-2);
133                        lua_concat(L,2);
134                        r = lua_isstring(L,-1) && strcmp(lua_tostring(L,-1),type)==0;
135                }
136        }
137        lua_pop(L, 1);
138        return r;
139}
140
141int push_table_instance(lua_State* L, int lo) {
142
143        if (lua_istable(L, lo)) {
144
145                lua_pushstring(L, ".c_instance");
146                lua_gettable(L, lo);
147                if (lua_isuserdata(L, -1)) {
148
149                        lua_replace(L, lo);
150                        return 1;
151                } else {
152
153                        lua_pop(L, 1);
154                        return 0;
155                };
156        } else {
157                return 0;
158        };
159
160        return 0;
161};
162
163/* the equivalent of lua_is* for usertype */
164static int lua_isusertype (lua_State* L, int lo, const char* type)
165{
166        if (!lua_isuserdata(L,lo)) {
167                if (!push_table_instance(L, lo)) {
168                        return 0;
169                };
170        };
171        {
172                /* check if it is of the same type */
173                int r;
174                const char *tn;
175                if (lua_getmetatable(L,lo))        /* if metatable? */
176                {
177                 lua_rawget(L,LUA_REGISTRYINDEX);  /* get registry[mt] */
178                 tn = lua_tostring(L,-1);
179                 r = tn && (strcmp(tn,type) == 0);
180                 lua_pop(L, 1);
181                        if (r)
182                         return 1;
183                        else
184                        {
185                                /* check if it is a specialized class */
186                                lua_pushstring(L,"tolua_super");
187                                lua_rawget(L,LUA_REGISTRYINDEX); /* get super */
188                                lua_getmetatable(L,lo);
189                                lua_rawget(L,-2);                /* get super[mt] */
190                                if (lua_istable(L,-1))
191                                {
192                                        int b;
193                                        lua_pushstring(L,type);
194                                        lua_rawget(L,-2);                /* get super[mt][type] */
195                                        b = lua_toboolean(L,-1);
196                                        lua_pop(L,3);
197                                        if (b)
198                                         return 1;
199                                }
200                        }
201                }
202 }
203        return 0;
204}
205
206TOLUA_API int tolua_isnoobj (lua_State* L, int lo, tolua_Error* err)
207{
208 if (lua_gettop(L)<abs(lo))
209                return 1;
210        err->index = lo;
211        err->array = 0;
212        err->type = "[no object]";
213 return 0;
214}
215
216TOLUA_API int tolua_isboolean (lua_State* L, int lo, int def, tolua_Error* err)
217{
218        if (def && lua_gettop(L)<abs(lo))
219                return 1;
220        if (lua_isnil(L,lo) || lua_isboolean(L,lo))
221                return 1;
222        err->index = lo;
223        err->array = 0;
224        err->type = "boolean";
225        return 0;
226}
227
228TOLUA_API int tolua_isnumber (lua_State* L, int lo, int def, tolua_Error* err)
229{
230        if (def && lua_gettop(L)<abs(lo))
231                return 1;
232        if (lua_isnumber(L,lo))
233                return 1;
234        err->index = lo;
235        err->array = 0;
236        err->type = "number";
237        return 0;
238}
239
240TOLUA_API int tolua_isstring (lua_State* L, int lo, int def, tolua_Error* err)
241{
242        if (def && lua_gettop(L)<abs(lo))
243                return 1;
244 if (lua_isnil(L,lo) || lua_isstring(L,lo))
245                return 1;
246        err->index = lo;
247        err->array = 0;
248        err->type = "string";
249        return 0;
250}
251
252TOLUA_API int tolua_istable (lua_State* L, int lo, int def, tolua_Error* err)
253{
254        if (def && lua_gettop(L)<abs(lo))
255                return 1;
256        if (lua_istable(L,lo))
257                return 1;
258        err->index = lo;
259        err->array = 0;
260        err->type = "table";
261        return 0;
262}
263
264TOLUA_API int tolua_isusertable (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
265{
266        if (def && lua_gettop(L)<abs(lo))
267                return 1;
268        if (lua_isusertable(L,lo,type))
269                return 1;
270        err->index = lo;
271        err->array = 0;
272        err->type = type;
273        return 0;
274}
275
276
277TOLUA_API int tolua_isuserdata (lua_State* L, int lo, int def, tolua_Error* err)
278{
279        if (def && lua_gettop(L)<abs(lo))
280                return 1;
281        if (lua_isnil(L,lo) || lua_isuserdata(L,lo))
282                return 1;
283        err->index = lo;
284        err->array = 0;
285        err->type = "userdata";
286        return 0;
287}
288
289TOLUA_API int tolua_isvaluenil (lua_State* L, int lo, tolua_Error* err) {
290
291        if (lua_gettop(L)<abs(lo))
292                return 0; /* somebody else should chack this */
293        if (!lua_isnil(L, lo))
294                return 0;
295       
296        err->index = lo;
297        err->array = 0;
298        err->type = "value";
299        return 1;
300};
301
302TOLUA_API int tolua_isvalue (lua_State* L, int lo, int def, tolua_Error* err)
303{
304        if (def || abs(lo)<=lua_gettop(L))  /* any valid index */
305                return 1;
306        err->index = lo;
307        err->array = 0;
308        err->type = "value";
309        return 0;
310}
311
312TOLUA_API int tolua_isusertype (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
313{
314        if (def && lua_gettop(L)<abs(lo))
315                return 1;
316        if (lua_isnil(L,lo) || lua_isusertype(L,lo,type))
317                return 1;
318        err->index = lo;
319        err->array = 0;
320        err->type = type;
321        return 0;
322}
323
324TOLUA_API int tolua_isvaluearray
325 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
326{
327        if (!tolua_istable(L,lo,def,err))
328                return 0;
329        else
330                return 1;
331}
332
333TOLUA_API int tolua_isbooleanarray
334 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
335{
336        if (!tolua_istable(L,lo,def,err))
337                return 0;
338        else
339        {
340                int i;
341                for (i=1; i<=dim; ++i)
342                {
343                        lua_pushnumber(L,i);
344                        lua_gettable(L,lo);
345          if (!(lua_isnil(L,-1) || lua_isboolean(L,-1)) &&
346                                          !(def && lua_isnil(L,-1))
347                                                )
348                        {
349                                err->index = lo;
350                                err->array = 1;
351                                err->type = "boolean";
352                                return 0;
353                        }
354                        lua_pop(L,1);
355                }
356 }
357 return 1;
358}
359
360TOLUA_API int tolua_isnumberarray
361 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
362{
363        if (!tolua_istable(L,lo,def,err))
364                return 0;
365        else
366        {
367                int i;
368                for (i=1; i<=dim; ++i)
369                {
370                        lua_pushnumber(L,i);
371                        lua_gettable(L,lo);
372                        if (!lua_isnumber(L,-1) &&
373                                          !(def && lua_isnil(L,-1))
374                                                )
375                        {
376                                err->index = lo;
377                                err->array = 1;
378                                err->type = "number";
379                                return 0;
380                        }
381                        lua_pop(L,1);
382                }
383 }
384 return 1;
385}
386
387TOLUA_API int tolua_isstringarray
388 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
389{
390        if (!tolua_istable(L,lo,def,err))
391                return 0;
392        else
393        {
394                int i;
395                for (i=1; i<=dim; ++i)
396                {
397                        lua_pushnumber(L,i);
398                        lua_gettable(L,lo);
399   if (!(lua_isnil(L,-1) || lua_isstring(L,-1)) &&
400                            !(def && lua_isnil(L,-1))
401                                                )
402                        {
403                                err->index = lo;
404                                err->array = 1;
405                                err->type = "string";
406                                return 0;
407                        }
408                        lua_pop(L,1);
409                }
410 }
411 return 1;
412}
413
414TOLUA_API int tolua_istablearray
415 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
416{
417        if (!tolua_istable(L,lo,def,err))
418                return 0;
419        else
420        {
421                int i;
422                for (i=1; i<=dim; ++i)
423                {
424                        lua_pushnumber(L,i);
425                        lua_gettable(L,lo);
426          if (! lua_istable(L,-1) &&
427                            !(def && lua_isnil(L,-1))
428                                                )
429                        {
430                                err->index = lo;
431                                err->array = 1;
432                                err->type = "table";
433                                return 0;
434                        }
435                        lua_pop(L,1);
436                }
437 }
438 return 1;
439}
440
441TOLUA_API int tolua_isuserdataarray
442 (lua_State* L, int lo, int dim, int def, tolua_Error* err)
443{
444        if (!tolua_istable(L,lo,def,err))
445                return 0;
446        else
447        {
448                int i;
449                for (i=1; i<=dim; ++i)
450                {
451                        lua_pushnumber(L,i);
452                        lua_gettable(L,lo);
453          if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
454                            !(def && lua_isnil(L,-1))
455                                                )
456                        {
457                                err->index = lo;
458                                err->array = 1;
459                                err->type = "userdata";
460                                return 0;
461                        }
462                        lua_pop(L,1);
463                }
464 }
465 return 1;
466}
467
468TOLUA_API int tolua_isusertypearray
469 (lua_State* L, int lo, const char* type, int dim, int def, tolua_Error* err)
470{
471        if (!tolua_istable(L,lo,def,err))
472                return 0;
473        else
474        {
475                int i;
476                for (i=1; i<=dim; ++i)
477                {
478                        lua_pushnumber(L,i);
479                        lua_gettable(L,lo);
480          if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
481                            !(def && lua_isnil(L,-1))
482                                                )
483                        {
484                                err->index = lo;
485                                err->type = type;
486                                err->array = 1;
487                                return 0;
488                        }
489                        lua_pop(L,1);
490                }
491 }
492 return 1;
493}
494
495#if 0
496int tolua_isbooleanfield
497 (lua_State* L, int lo, int i, int def, tolua_Error* err)
498{
499        lua_pushnumber(L,i);
500        lua_gettable(L,lo);
501        if (!(lua_isnil(L,-1) || lua_isboolean(L,-1)) &&
502                          !(def && lua_isnil(L,-1))
503                                )
504        {
505                err->index = lo;
506                err->array = 1;
507                err->type = "boolean";
508                return 0;
509        }
510        lua_pop(L,1);
511 return 1;
512}
513
514int tolua_isnumberfield
515 (lua_State* L, int lo, int i, int def, tolua_Error* err)
516{
517        lua_pushnumber(L,i);
518        lua_gettable(L,lo);
519        if (!lua_isnumber(L,-1) &&
520                          !(def && lua_isnil(L,-1))
521                                )
522        {
523                err->index = lo;
524                err->array = 1;
525                err->type = "number";
526                return 0;
527        }
528        lua_pop(L,1);
529 return 1;
530}
531
532int tolua_isstringfield
533 (lua_State* L, int lo, int i, int def, tolua_Error* err)
534{
535        lua_pushnumber(L,i);
536        lua_gettable(L,lo);
537 if (!(lua_isnil(L,-1) || lua_isstring(L,-1)) &&
538            !(def && lua_isnil(L,-1))
539                                )
540        {
541                err->index = lo;
542                err->array = 1;
543                err->type = "string";
544                return 0;
545        }
546        lua_pop(L,1);
547 return 1;
548}
549
550int tolua_istablefield
551 (lua_State* L, int lo, int i, int def, tolua_Error* err)
552{
553        lua_pushnumber(L,i+1);
554        lua_gettable(L,lo);
555        if (! lua_istable(L,-1) &&
556            !(def && lua_isnil(L,-1))
557                                )
558        {
559                err->index = lo;
560                err->array = 1;
561                err->type = "table";
562                return 0;
563        }
564        lua_pop(L,1);
565}
566
567int tolua_isusertablefield
568 (lua_State* L, int lo, const char* type, int i, int def, tolua_Error* err)
569{
570        lua_pushnumber(L,i);
571        lua_gettable(L,lo);
572        if (! lua_isusertable(L,-1,type) &&
573            !(def && lua_isnil(L,-1))
574                                )
575        {
576                err->index = lo;
577                err->array = 1;
578                err->type = type;
579                return 0;
580        }
581        lua_pop(L,1);
582 return 1;
583}
584
585int tolua_isuserdatafield
586 (lua_State* L, int lo, int i, int def, tolua_Error* err)
587{
588        lua_pushnumber(L,i);
589        lua_gettable(L,lo);
590        if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
591            !(def && lua_isnil(L,-1))
592                                )
593        {
594                err->index = lo;
595                err->array = 1;
596                err->type = "userdata";
597                return 0;
598        }
599        lua_pop(L,1);
600 return 1;
601}
602
603int tolua_isusertypefield
604 (lua_State* L, int lo, const char* type, int i, int def, tolua_Error* err)
605{
606        lua_pushnumber(L,i);
607        lua_gettable(L,lo);
608        if (!(lua_isnil(L,-1) || lua_isusertype(L,-1,type)) &&
609            !(def && lua_isnil(L,-1))
610                                )
611        {
612                err->index = lo;
613                err->type = type;
614                err->array = 1;
615                return 0;
616        }
617        lua_pop(L,1);
618 return 1;
619}
620
621#endif
Note: See TracBrowser for help on using the repository browser.