squirrel_std.cpp

00001 /* $Id: squirrel_std.cpp 15668 2009-03-11 07:32:31Z yexo $ */
00002 
00003 #include <squirrel.h>
00004 #include "../stdafx.h"
00005 #include "../debug.h"
00006 #include "squirrel.hpp"
00007 #include "squirrel_std.hpp"
00008 #include "../core/alloc_func.hpp"
00009 #include "../core/math_func.hpp"
00010 
00011 /* abs() is normally defined to myabs(), which we don't want in this file */
00012 #undef abs
00013 
00014 SQInteger SquirrelStd::abs(HSQUIRRELVM vm)
00015 {
00016   SQInteger tmp;
00017 
00018   sq_getinteger(vm, 2, &tmp);
00019   sq_pushinteger(vm, ::abs(tmp));
00020   return 1;
00021 }
00022 
00023 SQInteger SquirrelStd::min(HSQUIRRELVM vm)
00024 {
00025   SQInteger tmp1, tmp2;
00026 
00027   sq_getinteger(vm, 2, &tmp1);
00028   sq_getinteger(vm, 3, &tmp2);
00029   sq_pushinteger(vm, ::min(tmp1, tmp2));
00030   return 1;
00031 }
00032 
00033 SQInteger SquirrelStd::max(HSQUIRRELVM vm)
00034 {
00035   SQInteger tmp1, tmp2;
00036 
00037   sq_getinteger(vm, 2, &tmp1);
00038   sq_getinteger(vm, 3, &tmp2);
00039   sq_pushinteger(vm, ::max(tmp1, tmp2));
00040   return 1;
00041 }
00042 
00043 SQInteger SquirrelStd::require(HSQUIRRELVM vm)
00044 {
00045   SQInteger top = sq_gettop(vm);
00046   const SQChar *filename;
00047   SQChar *real_filename;
00048 
00049   sq_getstring(vm, 2, &filename);
00050 
00051   /* Get the script-name of the current file, so we can work relative from it */
00052   SQStackInfos si;
00053   sq_stackinfos(vm, 1, &si);
00054   if (si.source == NULL) {
00055     DEBUG(misc, 0, "[squirrel] Couldn't detect the script-name of the 'require'-caller; this should never happen!");
00056     return SQ_ERROR;
00057   }
00058   real_filename = scstrdup(si.source);
00059   /* Keep the dir, remove the rest */
00060   SQChar *s = scstrrchr(real_filename, PATHSEPCHAR);
00061   if (s != NULL) {
00062     /* Keep the PATHSEPCHAR there, remove the rest */
00063     *s++;
00064     *s = '\0';
00065   }
00066   /* And now we concat, so we are relative from the current script
00067    * First, we have to make sure we have enough space for the full path */
00068   real_filename = ReallocT(real_filename, scstrlen(real_filename) + scstrlen(filename) + 1);
00069   scstrcat(real_filename, filename);
00070   /* Tars dislike opening files with '/' on Windows.. so convert it to '\\' ;) */
00071   char *filen = strdup(FS2OTTD(real_filename));
00072 #if (PATHSEPCHAR != '/')
00073   for (char *n = filen; *n != '\0'; n++) if (*n == '/') *n = PATHSEPCHAR;
00074 #endif
00075 
00076   bool ret = Squirrel::LoadScript(vm, filen);
00077 
00078   /* Reset the top, so the stack stays correct */
00079   sq_settop(vm, top);
00080   free(real_filename);
00081   free(filen);
00082 
00083   return ret ? 0 : SQ_ERROR;
00084 }
00085 
00086 SQInteger SquirrelStd::notifyallexceptions(HSQUIRRELVM vm)
00087 {
00088   SQBool b;
00089 
00090   if (sq_gettop(vm) >= 1) {
00091     if (SQ_SUCCEEDED(sq_getbool(vm, -1, &b))) {
00092       sq_notifyallexceptions(vm, b);
00093       return 0;
00094     }
00095   }
00096 
00097   return SQ_ERROR;
00098 }
00099 
00100 void squirrel_register_global_std(Squirrel *engine)
00101 {
00102   /* We don't use squirrel_helper here, as we want to register to the global
00103    *  scope and not to a class. */
00104   engine->AddMethod("require",             &SquirrelStd::require,             2, ".s");
00105   engine->AddMethod("notifyallexceptions", &SquirrelStd::notifyallexceptions, 2, ".b");
00106 }
00107 
00108 void squirrel_register_std(Squirrel *engine)
00109 {
00110   /* We don't use squirrel_helper here, as we want to register to the global
00111    *  scope and not to a class. */
00112   engine->AddMethod("abs", &SquirrelStd::abs, 2, ".i");
00113   engine->AddMethod("min", &SquirrelStd::min, 3, ".ii");
00114   engine->AddMethod("max", &SquirrelStd::max, 3, ".ii");
00115 }

Generated on Tue Dec 1 00:06:19 2009 for OpenTTD by  doxygen 1.5.6