SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory. svghmi
authorEdouard Tisserant <edouard.tisserant@gmail.com>
Thu, 21 May 2020 11:29:45 +0200
branchsvghmi
changeset 2970 4a9b0df0602a
parent 2969 88988edb2e93
child 2971 f0a822ef9fa0
SVGHMI: stop using eval in change_hmi_value, apparently slowly leaking memory.
svghmi/gen_index_xhtml.xslt
svghmi/svghmi.js
--- a/svghmi/gen_index_xhtml.xslt	Thu May 14 17:49:20 2020 +0200
+++ b/svghmi/gen_index_xhtml.xslt	Thu May 21 11:29:45 2020 +0200
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
-<xsl:stylesheet xmlns:ns="beremiz" xmlns:definitions="definitions" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:func="http://exslt.org/functions" xmlns:epilogue="epilogue" xmlns:preamble="preamble" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:svg="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:str="http://exslt.org/strings" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:exsl="http://exslt.org/common" xmlns:declarations="declarations" xmlns:debug="debug" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions" extension-element-prefixes="ns func exsl regexp str dyn" version="1.0">
-  <xsl:output method="xml" cdata-section-elements="xhtml:script"/>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" xmlns:regexp="http://exslt.org/regular-expressions" xmlns:str="http://exslt.org/strings" xmlns:func="http://exslt.org/functions" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:debug="debug" xmlns:preamble="preamble" xmlns:declarations="declarations" xmlns:definitions="definitions" xmlns:epilogue="epilogue" xmlns:ns="beremiz" version="1.0" extension-element-prefixes="ns func exsl regexp str dyn" exclude-result-prefixes="ns func exsl regexp str dyn debug preamble epilogue declarations definitions">
+  <xsl:output cdata-section-elements="xhtml:script" method="xml"/>
   <xsl:variable name="svg" select="/svg:svg"/>
   <xsl:variable name="hmi_elements" select="//svg:*[starts-with(@inkscape:label, 'HMI:')]"/>
   <xsl:variable name="hmitree" select="ns:GetHMITree()"/>
@@ -1159,6 +1159,10 @@
 </xsl:text>
     <xsl:text>    init() {
 </xsl:text>
+    <xsl:text>        // TODO : use attributes to allow interaction through svg:use
+</xsl:text>
+    <xsl:text>        // TODO : deal with dragging
+</xsl:text>
     <xsl:text>        this.element.addEventListener(
 </xsl:text>
     <xsl:text>          "mousedown",
@@ -2700,7 +2704,7 @@
     <xsl:comment>
       <xsl:apply-templates select="document('')/*/debug:*"/>
     </xsl:comment>
-    <html xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/1999/xhtml">
+    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
       <head/>
       <body style="margin:0;overflow:hidden;">
         <xsl:copy-of select="$result_svg"/>
@@ -3235,13 +3239,41 @@
 </xsl:text>
           <xsl:text>
 </xsl:text>
+          <xsl:text>quotes = {"'":null, '"':null};
+</xsl:text>
+          <xsl:text>
+</xsl:text>
           <xsl:text>function change_hmi_value(index, opstr) {
 </xsl:text>
           <xsl:text>    let op = opstr[0];
 </xsl:text>
-          <xsl:text>    let given_val = opstr.slice(1);
-</xsl:text>
-          <xsl:text>    let old_val = cache[index]
+          <xsl:text>    let given_val;
+</xsl:text>
+          <xsl:text>    if(opstr.length &lt; 2) 
+</xsl:text>
+          <xsl:text>        return undefined; // TODO raise
+</xsl:text>
+          <xsl:text>    if(opstr[1] in quotes){
+</xsl:text>
+          <xsl:text>        if(opstr.length &lt; 3) 
+</xsl:text>
+          <xsl:text>            return undefined; // TODO raise
+</xsl:text>
+          <xsl:text>        if(opstr[opstr.length-1] == opstr[1]){
+</xsl:text>
+          <xsl:text>            given_val = opstr.slice(2,opstr.length-1);
+</xsl:text>
+          <xsl:text>        }
+</xsl:text>
+          <xsl:text>    } else {
+</xsl:text>
+          <xsl:text>        given_val = Number(opstr.slice(1));
+</xsl:text>
+          <xsl:text>    }
+</xsl:text>
+          <xsl:text>    console.log(opstr, given_val);
+</xsl:text>
+          <xsl:text>    let old_val = cache[index];
 </xsl:text>
           <xsl:text>    let new_val;
 </xsl:text>
@@ -3249,21 +3281,31 @@
 </xsl:text>
           <xsl:text>      case "=":
 </xsl:text>
-          <xsl:text>        eval("new_val"+opstr);
+          <xsl:text>        new_val = given_val;
 </xsl:text>
           <xsl:text>        break;
 </xsl:text>
           <xsl:text>      case "+":
 </xsl:text>
+          <xsl:text>        new_val = old_val + given_val;
+</xsl:text>
+          <xsl:text>        break;
+</xsl:text>
           <xsl:text>      case "-":
 </xsl:text>
+          <xsl:text>        new_val = old_val - given_val;
+</xsl:text>
+          <xsl:text>        break;
+</xsl:text>
           <xsl:text>      case "*":
 </xsl:text>
+          <xsl:text>        new_val = old_val * given_val;
+</xsl:text>
+          <xsl:text>        break;
+</xsl:text>
           <xsl:text>      case "/":
 </xsl:text>
-          <xsl:text>        if(old_val != undefined)
-</xsl:text>
-          <xsl:text>            new_val = eval("old_val"+opstr);
+          <xsl:text>        new_val = old_val / given_val;
 </xsl:text>
           <xsl:text>        break;
 </xsl:text>
@@ -3273,6 +3315,8 @@
 </xsl:text>
           <xsl:text>        send_hmi_value(index, new_val);
 </xsl:text>
+          <xsl:text>    // TODO else raise
+</xsl:text>
           <xsl:text>    return new_val;
 </xsl:text>
           <xsl:text>}
--- a/svghmi/svghmi.js	Thu May 14 17:49:20 2020 +0200
+++ b/svghmi/svghmi.js	Thu May 21 11:29:45 2020 +0200
@@ -247,25 +247,44 @@
     return new_val;
 }
 
+quotes = {"'":null, '"':null};
+
 function change_hmi_value(index, opstr) {
     let op = opstr[0];
-    let given_val = opstr.slice(1);
-    let old_val = cache[index]
+    let given_val;
+    if(opstr.length < 2) 
+        return undefined; // TODO raise
+    if(opstr[1] in quotes){
+        if(opstr.length < 3) 
+            return undefined; // TODO raise
+        if(opstr[opstr.length-1] == opstr[1]){
+            given_val = opstr.slice(2,opstr.length-1);
+        }
+    } else {
+        given_val = Number(opstr.slice(1));
+    }
+    let old_val = cache[index];
     let new_val;
     switch(op){
       case "=":
-        eval("new_val"+opstr);
+        new_val = given_val;
         break;
       case "+":
+        new_val = old_val + given_val;
+        break;
       case "-":
+        new_val = old_val - given_val;
+        break;
       case "*":
+        new_val = old_val * given_val;
+        break;
       case "/":
-        if(old_val != undefined)
-            new_val = eval("old_val"+opstr);
+        new_val = old_val / given_val;
         break;
     }
     if(new_val != undefined && old_val != new_val)
         send_hmi_value(index, new_val);
+    // TODO else raise
     return new_val;
 }