# squirrel_std.cpp

    00001 /* $Id: squirrel_std.cpp 15061 2009-01-13 15:49:32Z smatz $ */
    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 }