lbaselib.c

Go to the documentation of this file.
00001 /*
00002 ** $Id: lbaselib.c,v 1.191.1.6 2008/02/14 16:46:22 roberto Exp $
00003 ** Basic library
00004 ** See Copyright Notice in lua.h
00005 */
00006 
00007 
00008 
00009 #include <ctype.h>
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013 
00014 #define lbaselib_c
00015 #define LUA_LIB
00016 
00017 #include "lua.h"
00018 
00019 #include "lauxlib.h"
00020 #include "lualib.h"
00021 
00022 
00023 
00024 
00025 /*
00026 ** If your system does not support `stdout', you can just remove this function.
00027 ** If you need, you can define your own `print' function, following this
00028 ** model but changing `fputs' to put the strings at a proper place
00029 ** (a console window or a log file, for instance).
00030 */
00031 static int luaB_print (lua_State *L) {
00032   int n = lua_gettop(L);  /* number of arguments */
00033   int i;
00034   lua_getglobal(L, "tostring");
00035   for (i=1; i<=n; i++) {
00036     const char *s;
00037     lua_pushvalue(L, -1);  /* function to be called */
00038     lua_pushvalue(L, i);   /* value to print */
00039     lua_call(L, 1, 1);
00040     s = lua_tostring(L, -1);  /* get result */
00041     if (s == NULL)
00042       return luaL_error(L, LUA_QL("tostring") " must return a string to "
00043                            LUA_QL("print"));
00044     if (i>1) fputs("\t", stdout);
00045     fputs(s, stdout);
00046     lua_pop(L, 1);  /* pop result */
00047   }
00048   fputs("\n", stdout);
00049   return 0;
00050 }
00051 
00052 
00053 static int luaB_tonumber (lua_State *L) {
00054   int base = luaL_optint(L, 2, 10);
00055   if (base == 10) {  /* standard conversion */
00056     luaL_checkany(L, 1);
00057     if (lua_isnumber(L, 1)) {
00058       lua_pushnumber(L, lua_tonumber(L, 1));
00059       return 1;
00060     }
00061   }
00062   else {
00063     const char *s1 = luaL_checkstring(L, 1);
00064     char *s2;
00065     unsigned long n;
00066     luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
00067     n = strtoul(s1, &s2, base);
00068     if (s1 != s2) {  /* at least one valid digit? */
00069       while (isspace((unsigned char)(*s2))) s2++;  /* skip trailing spaces */
00070       if (*s2 == '\0') {  /* no invalid trailing characters? */
00071         lua_pushnumber(L, (lua_Number)n);
00072         return 1;
00073       }
00074     }
00075   }
00076   lua_pushnil(L);  /* else not a number */
00077   return 1;
00078 }
00079 
00080 
00081 static int luaB_error (lua_State *L) {
00082   int level = luaL_optint(L, 2, 1);
00083   lua_settop(L, 1);
00084   if (lua_isstring(L, 1) && level > 0) {  /* add extra information? */
00085     luaL_where(L, level);
00086     lua_pushvalue(L, 1);
00087     lua_concat(L, 2);
00088   }
00089   return lua_error(L);
00090 }
00091 
00092 
00093 static int luaB_getmetatable (lua_State *L) {
00094   luaL_checkany(L, 1);
00095   if (!lua_getmetatable(L, 1)) {
00096     lua_pushnil(L);
00097     return 1;  /* no metatable */
00098   }
00099   luaL_getmetafield(L, 1, "__metatable");
00100   return 1;  /* returns either __metatable field (if present) or metatable */
00101 }
00102 
00103 
00104 static int luaB_setmetatable (lua_State *L) {
00105   int t = lua_type(L, 2);
00106   luaL_checktype(L, 1, LUA_TTABLE);
00107   luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
00108                     "nil or table expected");
00109   if (luaL_getmetafield(L, 1, "__metatable"))
00110     luaL_error(L, "cannot change a protected metatable");
00111   lua_settop(L, 2);
00112   lua_setmetatable(L, 1);
00113   return 1;
00114 }
00115 
00116 
00117 static void getfunc (lua_State *L, int opt) {
00118   if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
00119   else {
00120     lua_Debug ar;
00121     int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
00122     luaL_argcheck(L, level >= 0, 1, "level must be non-negative");
00123     if (lua_getstack(L, level, &ar) == 0)
00124       luaL_argerror(L, 1, "invalid level");
00125     lua_getinfo(L, "f", &ar);
00126     if (lua_isnil(L, -1))
00127       luaL_error(L, "no function environment for tail call at level %d",
00128                     level);
00129   }
00130 }
00131 
00132 
00133 static int luaB_getfenv (lua_State *L) {
00134   getfunc(L, 1);
00135   if (lua_iscfunction(L, -1))  /* is a C function? */
00136     lua_pushvalue(L, LUA_GLOBALSINDEX);  /* return the thread's global env. */
00137   else
00138     lua_getfenv(L, -1);
00139   return 1;
00140 }
00141 
00142 
00143 static int luaB_setfenv (lua_State *L) {
00144   luaL_checktype(L, 2, LUA_TTABLE);
00145   getfunc(L, 0);
00146   lua_pushvalue(L, 2);
00147   if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
00148     /* change environment of current thread */
00149     lua_pushthread(L);
00150     lua_insert(L, -2);
00151     lua_setfenv(L, -2);
00152     return 0;
00153   }
00154   else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
00155     luaL_error(L,
00156           LUA_QL("setfenv") " cannot change environment of given object");
00157   return 1;
00158 }
00159 
00160 
00161 static int luaB_rawequal (lua_State *L) {
00162   luaL_checkany(L, 1);
00163   luaL_checkany(L, 2);
00164   lua_pushboolean(L, lua_rawequal(L, 1, 2));
00165   return 1;
00166 }
00167 
00168 
00169 static int luaB_rawget (lua_State *L) {
00170   luaL_checktype(L, 1, LUA_TTABLE);
00171   luaL_checkany(L, 2);
00172   lua_settop(L, 2);
00173   lua_rawget(L, 1);
00174   return 1;
00175 }
00176 
00177 static int luaB_rawset (lua_State *L) {
00178   luaL_checktype(L, 1, LUA_TTABLE);
00179   luaL_checkany(L, 2);
00180   luaL_checkany(L, 3);
00181   lua_settop(L, 3);
00182   lua_rawset(L, 1);
00183   return 1;
00184 }
00185 
00186 
00187 static int luaB_gcinfo (lua_State *L) {
00188   lua_pushinteger(L, lua_getgccount(L));
00189   return 1;
00190 }
00191 
00192 
00193 static int luaB_collectgarbage (lua_State *L) {
00194   static const char *const opts[] = {"stop", "restart", "collect",
00195     "count", "step", "setpause", "setstepmul", NULL};
00196   static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
00197     LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
00198   int o = luaL_checkoption(L, 1, "collect", opts);
00199   int ex = luaL_optint(L, 2, 0);
00200   int res = lua_gc(L, optsnum[o], ex);
00201   switch (optsnum[o]) {
00202     case LUA_GCCOUNT: {
00203       int b = lua_gc(L, LUA_GCCOUNTB, 0);
00204       lua_pushnumber(L, res + ((lua_Number)b/1024));
00205       return 1;
00206     }
00207     case LUA_GCSTEP: {
00208       lua_pushboolean(L, res);
00209       return 1;
00210     }
00211     default: {
00212       lua_pushnumber(L, res);
00213       return 1;
00214     }
00215   }
00216 }
00217 
00218 
00219 static int luaB_type (lua_State *L) {
00220   luaL_checkany(L, 1);
00221   lua_pushstring(L, luaL_typename(L, 1));
00222   return 1;
00223 }
00224 
00225 
00226 static int luaB_next (lua_State *L) {
00227   luaL_checktype(L, 1, LUA_TTABLE);
00228   lua_settop(L, 2);  /* create a 2nd argument if there isn't one */
00229   if (lua_next(L, 1))
00230     return 2;
00231   else {
00232     lua_pushnil(L);
00233     return 1;
00234   }
00235 }
00236 
00237 
00238 static int luaB_pairs (lua_State *L) {
00239   luaL_checktype(L, 1, LUA_TTABLE);
00240   lua_pushvalue(L, lua_upvalueindex(1));  /* return generator, */
00241   lua_pushvalue(L, 1);  /* state, */
00242   lua_pushnil(L);  /* and initial value */
00243   return 3;
00244 }
00245 
00246 
00247 static int ipairsaux (lua_State *L) {
00248   int i = luaL_checkint(L, 2);
00249   luaL_checktype(L, 1, LUA_TTABLE);
00250   i++;  /* next value */
00251   lua_pushinteger(L, i);
00252   lua_rawgeti(L, 1, i);
00253   return (lua_isnil(L, -1)) ? 0 : 2;
00254 }
00255 
00256 
00257 static int luaB_ipairs (lua_State *L) {
00258   luaL_checktype(L, 1, LUA_TTABLE);
00259   lua_pushvalue(L, lua_upvalueindex(1));  /* return generator, */
00260   lua_pushvalue(L, 1);  /* state, */
00261   lua_pushinteger(L, 0);  /* and initial value */
00262   return 3;
00263 }
00264 
00265 
00266 static int load_aux (lua_State *L, int status) {
00267   if (status == 0)  /* OK? */
00268     return 1;
00269   else {
00270     lua_pushnil(L);
00271     lua_insert(L, -2);  /* put before error message */
00272     return 2;  /* return nil plus error message */
00273   }
00274 }
00275 
00276 
00277 static int luaB_loadstring (lua_State *L) {
00278   size_t l;
00279   const char *s = luaL_checklstring(L, 1, &l);
00280   const char *chunkname = luaL_optstring(L, 2, s);
00281   return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
00282 }
00283 
00284 
00285 static int luaB_loadfile (lua_State *L) {
00286   const char *fname = luaL_optstring(L, 1, NULL);
00287   return load_aux(L, luaL_loadfile(L, fname));
00288 }
00289 
00290 
00291 /*
00292 ** Reader for generic `load' function: `lua_load' uses the
00293 ** stack for internal stuff, so the reader cannot change the
00294 ** stack top. Instead, it keeps its resulting string in a
00295 ** reserved slot inside the stack.
00296 */
00297 static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
00298   (void)ud;  /* to avoid warnings */
00299   luaL_checkstack(L, 2, "too many nested functions");
00300   lua_pushvalue(L, 1);  /* get function */
00301   lua_call(L, 0, 1);  /* call it */
00302   if (lua_isnil(L, -1)) {
00303     *size = 0;
00304     return NULL;
00305   }
00306   else if (lua_isstring(L, -1)) {
00307     lua_replace(L, 3);  /* save string in a reserved stack slot */
00308     return lua_tolstring(L, 3, size);
00309   }
00310   else luaL_error(L, "reader function must return a string");
00311   return NULL;  /* to avoid warnings */
00312 }
00313 
00314 
00315 static int luaB_load (lua_State *L) {
00316   int status;
00317   const char *cname = luaL_optstring(L, 2, "=(load)");
00318   luaL_checktype(L, 1, LUA_TFUNCTION);
00319   lua_settop(L, 3);  /* function, eventual name, plus one reserved slot */
00320   status = lua_load(L, generic_reader, NULL, cname);
00321   return load_aux(L, status);
00322 }
00323 
00324 
00325 static int luaB_dofile (lua_State *L) {
00326   const char *fname = luaL_optstring(L, 1, NULL);
00327   int n = lua_gettop(L);
00328   if (luaL_loadfile(L, fname) != 0) lua_error(L);
00329   lua_call(L, 0, LUA_MULTRET);
00330   return lua_gettop(L) - n;
00331 }
00332 
00333 
00334 static int luaB_assert (lua_State *L) {
00335   luaL_checkany(L, 1);
00336   if (!lua_toboolean(L, 1))
00337     return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!"));
00338   return lua_gettop(L);
00339 }
00340 
00341 
00342 static int luaB_unpack (lua_State *L) {
00343   int i, e, n;
00344   luaL_checktype(L, 1, LUA_TTABLE);
00345   i = luaL_optint(L, 2, 1);
00346   e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
00347   if (i > e) return 0;  /* empty range */
00348   n = e - i + 1;  /* number of elements */
00349   if (n <= 0 || !lua_checkstack(L, n))  /* n <= 0 means arith. overflow */
00350     return luaL_error(L, "too many results to unpack");
00351   lua_rawgeti(L, 1, i);  /* push arg[i] (avoiding overflow problems) */
00352   while (i++ < e)  /* push arg[i + 1...e] */
00353     lua_rawgeti(L, 1, i);
00354   return n;
00355 }
00356 
00357 
00358 static int luaB_select (lua_State *L) {
00359   int n = lua_gettop(L);
00360   if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') {
00361     lua_pushinteger(L, n-1);
00362     return 1;
00363   }
00364   else {
00365     int i = luaL_checkint(L, 1);
00366     if (i < 0) i = n + i;
00367     else if (i > n) i = n;
00368     luaL_argcheck(L, 1 <= i, 1, "index out of range");
00369     return n - i;
00370   }
00371 }
00372 
00373 
00374 static int luaB_pcall (lua_State *L) {
00375   int status;
00376   luaL_checkany(L, 1);
00377   status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
00378   lua_pushboolean(L, (status == 0));
00379   lua_insert(L, 1);
00380   return lua_gettop(L);  /* return status + all results */
00381 }
00382 
00383 
00384 static int luaB_xpcall (lua_State *L) {
00385   int status;
00386   luaL_checkany(L, 2);
00387   lua_settop(L, 2);
00388   lua_insert(L, 1);  /* put error function under function to be called */
00389   status = lua_pcall(L, 0, LUA_MULTRET, 1);
00390   lua_pushboolean(L, (status == 0));
00391   lua_replace(L, 1);
00392   return lua_gettop(L);  /* return status + all results */
00393 }
00394 
00395 
00396 static int luaB_tostring (lua_State *L) {
00397   luaL_checkany(L, 1);
00398   if (luaL_callmeta(L, 1, "__tostring"))  /* is there a metafield? */
00399     return 1;  /* use its value */
00400   switch (lua_type(L, 1)) {
00401     case LUA_TNUMBER:
00402       lua_pushstring(L, lua_tostring(L, 1));
00403       break;
00404     case LUA_TSTRING:
00405       lua_pushvalue(L, 1);
00406       break;
00407     case LUA_TBOOLEAN:
00408       lua_pushstring(L, (lua_toboolean(L, 1) ? "true" : "false"));
00409       break;
00410     case LUA_TNIL:
00411       lua_pushliteral(L, "nil");
00412       break;
00413     default:
00414       lua_pushfstring(L, "%s: %p", luaL_typename(L, 1), lua_topointer(L, 1));
00415       break;
00416   }
00417   return 1;
00418 }
00419 
00420 
00421 static int luaB_newproxy (lua_State *L) {
00422   lua_settop(L, 1);
00423   lua_newuserdata(L, 0);  /* create proxy */
00424   if (lua_toboolean(L, 1) == 0)
00425     return 1;  /* no metatable */
00426   else if (lua_isboolean(L, 1)) {
00427     lua_newtable(L);  /* create a new metatable `m' ... */
00428     lua_pushvalue(L, -1);  /* ... and mark `m' as a valid metatable */
00429     lua_pushboolean(L, 1);
00430     lua_rawset(L, lua_upvalueindex(1));  /* weaktable[m] = true */
00431   }
00432   else {
00433     int validproxy = 0;  /* to check if weaktable[metatable(u)] == true */
00434     if (lua_getmetatable(L, 1)) {
00435       lua_rawget(L, lua_upvalueindex(1));
00436       validproxy = lua_toboolean(L, -1);
00437       lua_pop(L, 1);  /* remove value */
00438     }
00439     luaL_argcheck(L, validproxy, 1, "boolean or proxy expected");
00440     lua_getmetatable(L, 1);  /* metatable is valid; get it */
00441   }
00442   lua_setmetatable(L, 2);
00443   return 1;
00444 }
00445 
00446 
00447 static const luaL_Reg base_funcs[] = {
00448   {"assert", luaB_assert},
00449   {"collectgarbage", luaB_collectgarbage},
00450   {"dofile", luaB_dofile},
00451   {"error", luaB_error},
00452   {"gcinfo", luaB_gcinfo},
00453   {"getfenv", luaB_getfenv},
00454   {"getmetatable", luaB_getmetatable},
00455   {"loadfile", luaB_loadfile},
00456   {"load", luaB_load},
00457   {"loadstring", luaB_loadstring},
00458   {"next", luaB_next},
00459   {"pcall", luaB_pcall},
00460   {"print", luaB_print},
00461   {"rawequal", luaB_rawequal},
00462   {"rawget", luaB_rawget},
00463   {"rawset", luaB_rawset},
00464   {"select", luaB_select},
00465   {"setfenv", luaB_setfenv},
00466   {"setmetatable", luaB_setmetatable},
00467   {"tonumber", luaB_tonumber},
00468   {"tostring", luaB_tostring},
00469   {"type", luaB_type},
00470   {"unpack", luaB_unpack},
00471   {"xpcall", luaB_xpcall},
00472   {NULL, NULL}
00473 };
00474 
00475 
00476 /*
00477 ** {======================================================
00478 ** Coroutine library
00479 ** =======================================================
00480 */
00481 
00482 #define CO_RUN  0   /* running */
00483 #define CO_SUS  1   /* suspended */
00484 #define CO_NOR  2   /* 'normal' (it resumed another coroutine) */
00485 #define CO_DEAD 3
00486 
00487 static const char *const statnames[] =
00488     {"running", "suspended", "normal", "dead"};
00489 
00490 static int costatus (lua_State *L, lua_State *co) {
00491   if (L == co) return CO_RUN;
00492   switch (lua_status(co)) {
00493     case LUA_YIELD:
00494       return CO_SUS;
00495     case 0: {
00496       lua_Debug ar;
00497       if (lua_getstack(co, 0, &ar) > 0)  /* does it have frames? */
00498         return CO_NOR;  /* it is running */
00499       else if (lua_gettop(co) == 0)
00500           return CO_DEAD;
00501       else
00502         return CO_SUS;  /* initial state */
00503     }
00504     default:  /* some error occured */
00505       return CO_DEAD;
00506   }
00507 }
00508 
00509 
00510 static int luaB_costatus (lua_State *L) {
00511   lua_State *co = lua_tothread(L, 1);
00512   luaL_argcheck(L, co, 1, "coroutine expected");
00513   lua_pushstring(L, statnames[costatus(L, co)]);
00514   return 1;
00515 }
00516 
00517 
00518 static int auxresume (lua_State *L, lua_State *co, int narg) {
00519   int status = costatus(L, co);
00520   if (!lua_checkstack(co, narg))
00521     luaL_error(L, "too many arguments to resume");
00522   if (status != CO_SUS) {
00523     lua_pushfstring(L, "cannot resume %s coroutine", statnames[status]);
00524     return -1;  /* error flag */
00525   }
00526   lua_xmove(L, co, narg);
00527   lua_setlevel(L, co);
00528   status = lua_resume(co, narg);
00529   if (status == 0 || status == LUA_YIELD) {
00530     int nres = lua_gettop(co);
00531     if (!lua_checkstack(L, nres + 1))
00532       luaL_error(L, "too many results to resume");
00533     lua_xmove(co, L, nres);  /* move yielded values */
00534     return nres;
00535   }
00536   else {
00537     lua_xmove(co, L, 1);  /* move error message */
00538     return -1;  /* error flag */
00539   }
00540 }
00541 
00542 
00543 static int luaB_coresume (lua_State *L) {
00544   lua_State *co = lua_tothread(L, 1);
00545   int r;
00546   luaL_argcheck(L, co, 1, "coroutine expected");
00547   r = auxresume(L, co, lua_gettop(L) - 1);
00548   if (r < 0) {
00549     lua_pushboolean(L, 0);
00550     lua_insert(L, -2);
00551     return 2;  /* return false + error message */
00552   }
00553   else {
00554     lua_pushboolean(L, 1);
00555     lua_insert(L, -(r + 1));
00556     return r + 1;  /* return true + `resume' returns */
00557   }
00558 }
00559 
00560 
00561 static int luaB_auxwrap (lua_State *L) {
00562   lua_State *co = lua_tothread(L, lua_upvalueindex(1));
00563   int r = auxresume(L, co, lua_gettop(L));
00564   if (r < 0) {
00565     if (lua_isstring(L, -1)) {  /* error object is a string? */
00566       luaL_where(L, 1);  /* add extra info */
00567       lua_insert(L, -2);
00568       lua_concat(L, 2);
00569     }
00570     lua_error(L);  /* propagate error */
00571   }
00572   return r;
00573 }
00574 
00575 
00576 static int luaB_cocreate (lua_State *L) {
00577   lua_State *NL = lua_newthread(L);
00578   luaL_argcheck(L, lua_isfunction(L, 1) && !lua_iscfunction(L, 1), 1,
00579     "Lua function expected");
00580   lua_pushvalue(L, 1);  /* move function to top */
00581   lua_xmove(L, NL, 1);  /* move function from L to NL */
00582   return 1;
00583 }
00584 
00585 
00586 static int luaB_cowrap (lua_State *L) {
00587   luaB_cocreate(L);
00588   lua_pushcclosure(L, luaB_auxwrap, 1);
00589   return 1;
00590 }
00591 
00592 
00593 static int luaB_yield (lua_State *L) {
00594   return lua_yield(L, lua_gettop(L));
00595 }
00596 
00597 
00598 static int luaB_corunning (lua_State *L) {
00599   if (lua_pushthread(L))
00600     lua_pushnil(L);  /* main thread is not a coroutine */
00601   return 1;
00602 }
00603 
00604 
00605 static const luaL_Reg co_funcs[] = {
00606   {"create", luaB_cocreate},
00607   {"resume", luaB_coresume},
00608   {"running", luaB_corunning},
00609   {"status", luaB_costatus},
00610   {"wrap", luaB_cowrap},
00611   {"yield", luaB_yield},
00612   {NULL, NULL}
00613 };
00614 
00615 /* }====================================================== */
00616 
00617 
00618 static void auxopen (lua_State *L, const char *name,
00619                      lua_CFunction f, lua_CFunction u) {
00620   lua_pushcfunction(L, u);
00621   lua_pushcclosure(L, f, 1);
00622   lua_setfield(L, -2, name);
00623 }
00624 
00625 
00626 static void base_open (lua_State *L) {
00627   /* set global _G */
00628   lua_pushvalue(L, LUA_GLOBALSINDEX);
00629   lua_setglobal(L, "_G");
00630   /* open lib into global table */
00631   luaL_register(L, "_G", base_funcs);
00632   lua_pushliteral(L, LUA_VERSION);
00633   lua_setglobal(L, "_VERSION");  /* set global _VERSION */
00634   /* `ipairs' and `pairs' need auxliliary functions as upvalues */
00635   auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
00636   auxopen(L, "pairs", luaB_pairs, luaB_next);
00637   /* `newproxy' needs a weaktable as upvalue */
00638   lua_createtable(L, 0, 1);  /* new table `w' */
00639   lua_pushvalue(L, -1);  /* `w' will be its own metatable */
00640   lua_setmetatable(L, -2);
00641   lua_pushliteral(L, "kv");
00642   lua_setfield(L, -2, "__mode");  /* metatable(w).__mode = "kv" */
00643   lua_pushcclosure(L, luaB_newproxy, 1);
00644   lua_setglobal(L, "newproxy");  /* set global `newproxy' */
00645 }
00646 
00647 
00648 LUALIB_API int luaopen_base (lua_State *L) {
00649   base_open(L);
00650   luaL_register(L, LUA_COLIBNAME, co_funcs);
00651   return 2;
00652 }

Generated by  doxygen 1.6.2