]> git.mxchange.org Git - flightgear.git/blobdiff - src/Scripting/nasal-props.cxx
- fix two bugs
[flightgear.git] / src / Scripting / nasal-props.cxx
index de0efca33fac241c29c8835dcc481b41663fb243..aba10f6a598565480e6f043acde206163a61b85d 100644 (file)
@@ -1,3 +1,8 @@
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
 #include <simgear/nasal/nasal.h>
 #include <simgear/props/props.hxx>
 
@@ -25,6 +30,7 @@ naGhostType PropNodeGhostType = { propNodeGhostDestroy };
 
 static naRef propNodeGhostCreate(naContext c, SGPropertyNode* n)
 {
+    if(!n) return naNil();
     SGPropertyNode_ptr* ghost = new SGPropertyNode_ptr(n);
     return naNewGhost(c, &PropNodeGhostType, ghost);
 }
@@ -43,17 +49,14 @@ naRef FGNasalSys::propNodeGhost(SGPropertyNode* handle)
 // array.  This allows the Nasal handlers to do things like:
 //   Node.getChild = func { _getChild(me.ghost, arg) }
 //
-#define NODEARG() \
-    naRef ghost = naVec_get(args, 0); \
-    SGPropertyNode_ptr* node = (SGPropertyNode_ptr*)naGhost_ptr(ghost); \
-    if(!node || naGhost_type(ghost) != &PropNodeGhostType) \
-        return naNil(); \
-    if(naVec_size(args) > 1) { \
-        args = naVec_get(args, 1); \
-        if(!naIsVector(args)) return naNil(); \
-    } else { args = naNil(); }
-
-static naRef f_getType(naContext c, naRef args)
+#define NODEARG()                                                       \
+    if(argc < 2 || !naIsGhost(args[0]) ||                               \
+       naGhost_type(args[0]) != &PropNodeGhostType)                       \
+        naRuntimeError(c, "bad argument to props function");            \
+    SGPropertyNode_ptr* node = (SGPropertyNode_ptr*)naGhost_ptr(args[0]); \
+    naRef argv = args[1]
+
+static naRef f_getType(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
     char* t = "unknown";
@@ -71,19 +74,19 @@ static naRef f_getType(naContext c, naRef args)
     return NASTR(t);
 }
 
-static naRef f_getName(naContext c, naRef args)
+static naRef f_getName(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
     return NASTR((*node)->getName());
 }
 
-static naRef f_getIndex(naContext c, naRef args)
+static naRef f_getIndex(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
     return naNum((*node)->getIndex());
 }
 
-static naRef f_getValue(naContext c, naRef args)
+static naRef f_getValue(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
     switch((*node)->getType()) {
@@ -98,39 +101,47 @@ static naRef f_getValue(naContext c, naRef args)
     return naNil();
 }
 
-static naRef f_setValue(naContext c, naRef args)
+static naRef f_setValue(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
-    naRef val = naVec_get(args, 0);
+    naRef val = naVec_get(argv, 0);
     if(naIsString(val)) (*node)->setStringValue(naStr_data(val));
     else                (*node)->setDoubleValue(naNumValue(val).num);
     return naNil();
 }
 
-static naRef f_setIntValue(naContext c, naRef args)
+static naRef f_setIntValue(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
-    int iv = (int)naNumValue(naVec_get(args, 0)).num;
+    // Original code:
+    //   int iv = (int)naNumValue(naVec_get(argv, 0)).num;
+
+    // Junk to pacify the gcc-2.95.3 optimizer:
+    naRef tmp0 = naVec_get(argv, 0);
+    naRef tmp1 = naNumValue(tmp0);
+    double tmp2 = tmp1.num;
+    int iv = (int)tmp2;
+
     (*node)->setIntValue(iv);
     return naNil();
 }
 
-static naRef f_setBoolValue(naContext c, naRef args)
+static naRef f_setBoolValue(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
-    naRef val = naVec_get(args, 0);
+    naRef val = naVec_get(argv, 0);
     (*node)->setBoolValue(naTrue(val) ? true : false);
     return naNil();
 }
 
-static naRef f_setDoubleValue(naContext c, naRef args)
+static naRef f_setDoubleValue(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
-    (*node)->setDoubleValue(naNumValue(naVec_get(args, 0)).num);
+    (*node)->setDoubleValue(naNumValue(naVec_get(argv, 0)).num);
     return naNil();
 }
 
-static naRef f_getParent(naContext c, naRef args)
+static naRef f_getParent(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
     SGPropertyNode* n = (*node)->getParent();
@@ -138,67 +149,119 @@ static naRef f_getParent(naContext c, naRef args)
     return propNodeGhostCreate(c, n);
 }
 
-static naRef f_getChild(naContext c, naRef args)
+static naRef f_getChild(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
-    naRef child = naVec_get(args, 0);
+    naRef child = naVec_get(argv, 0);
     if(!naIsString(child)) return naNil();
-    SGPropertyNode* n = (*node)->getChild(naStr_data(child));
+    naRef idx = naNumValue(naVec_get(argv, 1));
+    bool create = naTrue(naVec_get(argv, 2));
+    SGPropertyNode* n;
+    try {
+        if(naIsNil(idx) || !naIsNum(idx)) {
+            n = (*node)->getChild(naStr_data(child), create);
+        } else {
+            n = (*node)->getChild(naStr_data(child), (int)idx.num, create);
+        }
+    } catch (const string& err) {
+        naRuntimeError(c, (char *)err.c_str());
+        return naNil();
+    }
     if(!n) return naNil();
     return propNodeGhostCreate(c, n);
 }
 
-static naRef f_getChildren(naContext c, naRef args)
+static naRef f_getChildren(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
     naRef result = naNewVector(c);
-    if(naIsNil(args) || naVec_size(args) == 0) {
+    if(naIsNil(argv) || naVec_size(argv) == 0) {
         // Get all children
         for(int i=0; i<(*node)->nChildren(); i++)
             naVec_append(result, propNodeGhostCreate(c, (*node)->getChild(i)));
     } else {
         // Get all children of a specified name
-        naRef name = naVec_get(args, 0);
+        naRef name = naVec_get(argv, 0);
         if(!naIsString(name)) return naNil();
-        vector<SGPropertyNode_ptr> children
-            = (*node)->getChildren(naStr_data(name));
-        for(int i=0; i<children.size(); i++)
-            naVec_append(result, propNodeGhostCreate(c, children[i]));
+        try {
+            vector<SGPropertyNode_ptr> children
+                = (*node)->getChildren(naStr_data(name));
+            for(unsigned int i=0; i<children.size(); i++)
+                naVec_append(result, propNodeGhostCreate(c, children[i]));
+        } catch (const string& err) {
+            naRuntimeError(c, (char *)err.c_str());
+            return naNil();
+        }
     }
     return result;
 }
 
-static naRef f_removeChild(naContext c, naRef args)
+static naRef f_removeChild(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
-    naRef child = naVec_get(args, 0);
-    naRef index = naVec_get(args, 1);
+    naRef child = naVec_get(argv, 0);
+    naRef index = naVec_get(argv, 1);
     if(!naIsString(child) || !naIsNum(index)) return naNil();
-    (*node)->removeChild(naStr_data(child), (int)index.num);
+    try {
+        (*node)->removeChild(naStr_data(child), (int)index.num, false);
+    } catch (const string& err) {
+        naRuntimeError(c, (char *)err.c_str());
+    }
     return naNil();
 }
 
-static naRef f_getNode(naContext c, naRef args)
+static naRef f_removeChildren(naContext c, naRef me, int argc, naRef* args)
+{
+    NODEARG();
+    naRef result = naNewVector(c);
+    if(naIsNil(argv) || naVec_size(argv) == 0) {
+        // Remove all children
+        for(int i = (*node)->nChildren() - 1; i >=0; i--)
+            naVec_append(result, propNodeGhostCreate(c, (*node)->removeChild(i)));
+    } else {
+        // Remove all children of a specified name
+        naRef name = naVec_get(argv, 0);
+        if(!naIsString(name)) return naNil();
+        try {
+            vector<SGPropertyNode_ptr> children
+                = (*node)->removeChildren(naStr_data(name), false);
+            for(unsigned int i=0; i<children.size(); i++)
+                naVec_append(result, propNodeGhostCreate(c, children[i]));
+        } catch (const string& err) {
+            naRuntimeError(c, (char *)err.c_str());
+            return naNil();
+        }
+    }
+    return result;
+}
+
+static naRef f_getNode(naContext c, naRef me, int argc, naRef* args)
 {
     NODEARG();
-    naRef path = naVec_get(args, 0);
-    bool create = naTrue(naVec_get(args, 1));
+    naRef path = naVec_get(argv, 0);
+    bool create = naTrue(naVec_get(argv, 1));
     if(!naIsString(path)) return naNil();
-    SGPropertyNode* n = (*node)->getNode(naStr_data(path), create);
+    SGPropertyNode* n;
+    try {
+        n = (*node)->getNode(naStr_data(path), create);
+    } catch (const string& err) {
+        naRuntimeError(c, (char *)err.c_str());
+        return naNil();
+    }
     return propNodeGhostCreate(c, n);
 }
 
-static naRef f_new(naContext c, naRef args)
+static naRef f_new(naContext c, naRef me, int argc, naRef* args)
 {
     return propNodeGhostCreate(c, new SGPropertyNode());
 }
 
-static naRef f_globals(naContext c, naRef args)
+static naRef f_globals(naContext c, naRef me, int argc, naRef* args)
 {
     return propNodeGhostCreate(c, globals->get_props());
 }
 
-struct {
+static struct {
     naCFunction func;
     char* name;
 } propfuncs[] = {
@@ -214,6 +277,7 @@ struct {
     { f_getChild, "_getChild" },
     { f_getChildren, "_getChildren" },
     { f_removeChild, "_removeChild" },
+    { f_removeChildren, "_removeChildren" },
     { f_getNode, "_getNode" },
     { f_new, "_new" },
     { f_globals, "_globals" },