* Bug 15898 fixed: edit() with user-defined | alias of macro 54/20654/4
Samuel GOUGEON [Sun, 9 Dec 2018 04:14:24 +0000 (05:14 +0100)]
  http://bugzilla.scilab.org/15898

  edit() help pages are already in the [scinotes] module.
  edit() had not yet any unit tests.

Change-Id: Ib92c656e2b9fd9e0fd67c174281336defbb8c977

scilab/CHANGES.md
scilab/modules/core/macros/edit.sci [deleted file]
scilab/modules/scinotes/macros/edit.sci [new file with mode: 0644]
scilab/modules/scinotes/tests/unit_tests/edit.tst [new file with mode: 0644]

index f819cbb..0f5dd32 100644 (file)
@@ -692,6 +692,7 @@ Known issues
 * [#15886](http://bugzilla.scilab.org/show_bug.cgi?id=15886): Display of polynomials was broken.
 * [#15890](http://bugzilla.scilab.org/show_bug.cgi?id=15890): `evstr` sometimes yielded some `+[]` warnings.
 * [#15891](http://bugzilla.scilab.org/show_bug.cgi?id=15891): Help pages of matrix-wise trigonometrical functions deserved a dedicated subsection.
+* [#15898](http://bugzilla.scilab.org/show_bug.cgi?id=15898): `edit` failed 1) for any user-defined macro  2) for a native macro recompiled from Scinotes  3) for a native macro addressed through an alias (as sine=sind)
 * [#15899](http://bugzilla.scilab.org/show_bug.cgi?id=15899): `tree2code(tree, prettyprint=%t)` ignored the indentation width declared in Scinotes preferences.
 * [#15907](http://bugzilla.scilab.org/show_bug.cgi?id=15907): `filter` was corrupting its input state array
 * [#15920](http://bugzilla.scilab.org/show_bug.cgi?id=15920): genlib() did not regenerate a missing .bin if the .sci was unchanged (Scilab 6 regression)
diff --git a/scilab/modules/core/macros/edit.sci b/scilab/modules/core/macros/edit.sci
deleted file mode 100644 (file)
index b520a24..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) ????-2008 - INRIA
-// Copyright (C) 2008 - INRIA - Allan CORNET
-// Copyright (C) 2010 - DIGITEO - Allan CORNET
-//
-// Copyright (C) 2012 - 2016 - Scilab Enterprises
-//
-// This file is hereby licensed under the terms of the GNU GPL v2.0,
-// pursuant to article 5.3.4 of the CeCILL v.2.1.
-// This file was originally licensed under the terms of the CeCILL v2.1,
-// and continues to be available under such terms.
-// For more information, see the COPYING file which you should have received
-// along with this program.
-
-function edit(macroname,linenumber)
-    // macroname : character string giving a macroname
-    // linenumber : line number
-
-    [lhs,rhs] = argn(0);
-    if (rhs > 2) then
-        error(sprintf(gettext("%s: Wrong number of input argument(s): At least %d expected.\n"), "edit", 1));
-    end
-
-    if (rhs >= 1 & type(macroname) ~= 10) then
-        error(sprintf(gettext("%s: Wrong type for input argument #%d: String expected.\n"),"edit",1));
-    end
-
-    if (rhs == 2 & type(linenumber) ~= 1) then
-        error(msprintf(gettext("%s: Wrong type for input argument #%d: Double expected.\n"),"edit",2));
-    end
-
-    found = %f;
-    tmp = %f;
-    // tmpdir will have trailing / or \
-    tmpdir= pathconvert(TMPDIR);
-
-    if rhs >= 1 then // macroname or filename is given
-        if regexp(macroname, "/^([a-zA-Z%_#!$?][0-9a-zA-Z_#!$?]*)$/") == [] then
-            fname = macroname;
-            found = %t;
-        else
-            tmpfile = tmpdir + macroname + ".sci";
-            if funptr(macroname)<>0 then
-                error(msprintf(gettext("%s: %s is an uneditable hard coded function.\n"), "edit", macroname));
-            end
-            libr = whereis(macroname);
-            if libr <> [] then // macroname is the name of a defined function
-                if size(libr, "*") > 1 then
-                    // we take last definition
-                    libr = libr(1);
-                end
-                [macrolist, path] = libraryinfo(libr);
-                clear macrolist;
-                // convert path according to getos() == "Windows" value and expand SCI
-                fname = pathconvert(path) + macroname + ".sci";
-                found = isfile(fname);
-            elseif isdef(macroname)
-                if typeof(evstr(macroname)) == "function" then
-                    txt = tree2code(macr2tree(evstr(macroname)));
-                    fname = tmpfile;
-                    mputl(txt, fname);
-                    found = %t;
-                end
-            end
-        end
-    else //no macroname specified
-        macroname = "untitled";
-        tmpfile = tmpdir + macroname + ".sci";
-        found = %f;
-    end
-
-    if ~found then // macroname is the name of an undefined function
-        fname = tmpfile;
-        txt = ["function [] = " + macroname + "()"; "endfunction"];
-        mputl(txt, fname);
-    end
-
-    // call the editor with the filename
-    if (rhs == 2) then
-        editor(fname, linenumber, macroname);
-    else
-        editor(fname);
-    end
-
-endfunction
diff --git a/scilab/modules/scinotes/macros/edit.sci b/scilab/modules/scinotes/macros/edit.sci
new file mode 100644 (file)
index 0000000..8c30775
--- /dev/null
@@ -0,0 +1,127 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) ????-2008 - INRIA
+// Copyright (C) 2008 - INRIA - Allan CORNET
+// Copyright (C) 2010 - DIGITEO - Allan CORNET
+// Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2018 - Samuel GOUGEON
+//
+// This file is hereby licensed under the terms of the GNU GPL v2.0,
+// pursuant to article 5.3.4 of the CeCILL v.2.1.
+// This file was originally licensed under the terms of the CeCILL v2.1,
+// and continues to be available under such terms.
+// For more information, see the COPYING file which you should have received
+// along with this program.
+
+function edit(macroname, linenumber)
+    // macroname : character string giving a macroname
+    // linenumber : line number
+
+    [lhs,rhs] = argn(0);
+    if (rhs > 2) then
+        error(sprintf(gettext("%s: Wrong number of input argument(s): At least %d expected.\n"), "edit", 1));
+    end
+
+    if (rhs >= 1 & type(macroname) ~= 10) then
+        error(sprintf(gettext("%s: Wrong type for input argument #%d: String expected.\n"),"edit",1));
+    end
+
+    if (rhs == 2 & type(linenumber) ~= 1) then
+        error(msprintf(gettext("%s: Wrong type for input argument #%d: Double expected.\n"),"edit",2));
+    end
+
+    found = %f;
+    tmp = %f;
+    // tmpdir will have trailing / or \
+    tmpdir= pathconvert(TMPDIR);
+
+    if rhs >= 1 then // macroname or filename is given
+        if regexp(macroname, "/^([a-zA-Z%_#!$?][0-9a-zA-Z_#!$?]*)$/") == [] then
+            // File
+            fname = macroname;
+            found = %t;
+        else
+            if isdef(macroname)
+                execstr("object = "+macroname)
+                if type(object)==13
+                    // macroname may be an alias. Example: sinus = sind
+                    // We need to get the original macro name to edit it:
+                    tree = macr2tree(object);
+                    tmp = tree.name
+                    if tmp ~= macroname then
+                        msg = _("edit: ""%s"" is an alias of ""%s"" => editing %s()\n      Please reset %s=%s if %s() is recompiled.\n")
+                        warning(msprintf(msg, macroname, tmp, tmp, macroname, tmp, tmp))
+                        macroname = tmp
+                    end
+
+                    libr = whereis(macroname);
+                    if type(libr($))==10 & libr($)=="script"
+                        // the user-defined macro may overwrite a macro in library
+                        path = whereis_in_libs(macroname)
+                        if path ~= []
+                            // priority = from library:
+                            fname = pathconvert(path) + macroname + ".sci"
+                        else
+                            txt = tree2code(tree, %t);
+                            fname = tmpdir + macroname + ".sci";
+                            mputl(txt, fname);
+                        end
+                        found = %t
+                    else // libr is either a module name or a library name
+                        libr = libr($)
+                        err = execstr("tmp="+libr, "errcatch")
+                        if ~err & type(tmp)==14
+                            [macrolist, path] = libraryinfo(libr);
+                            fname = pathconvert(path) + macroname + ".sci"
+                            found = %t
+                        else // either a module name or any variable name:
+                            // If macroname is a user-defined function,
+                            // whereis() would have reported it as "script".
+                            // => it's a macro in a library, but with a
+                            // macroname equal to a built-in name
+                            // => we must retrieve the library without whereis()
+                            path = whereis_in_libs(macroname)
+                            if path ~= []
+                                fname = pathconvert(path) + macroname + ".sci"
+                                found = %t
+                            end
+                        end
+                    end
+                end
+
+                if ~found & funptr(macroname)<>0 then
+                    error(msprintf(gettext("%s: %s() is an uneditable hard coded function.\n"), "edit", macroname));
+                end
+            end
+        end
+    end
+
+    if ~found
+        if ~isdef("macroname","l")
+            macroname = "untitled"
+        end
+        fname = tmpdir + macroname + ".sci";
+        txt = ["function [] = " + macroname + "()"; "endfunction"];
+        mputl(txt, fname);
+    end
+
+    // call the editor with the filename
+    if (rhs == 2) then
+        editor(fname, linenumber, macroname);
+    else
+        editor(fname);
+    end
+
+endfunction
+
+// ----------------------------------------------------------------------------
+
+function path = whereis_in_libs(macroname)
+    path = []
+    for l = librarieslist()'
+        [m, p] = libraryinfo(l)
+        if or(m==macroname)
+            path = p
+            break
+        end
+    end
+endfunction
diff --git a/scilab/modules/scinotes/tests/unit_tests/edit.tst b/scilab/modules/scinotes/tests/unit_tests/edit.tst
new file mode 100644 (file)
index 0000000..fd564c6
--- /dev/null
@@ -0,0 +1,106 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2018 - Samuel GOUGEON
+//
+// This file is hereby licensed under the terms of the GNU GPL v2.0,
+// pursuant to article 5.3.4 of the CeCILL v.2.1.
+// This file was originally licensed under the terms of the CeCILL v2.1,
+// and continues to be available under such terms.
+// For more information, see the COPYING file which you should have received
+// along with this program.
+// =============================================================================
+//                          Unitary tests for edit()
+// =============================================================================
+
+// <-- INTERACTIVE TEST -->
+
+// 1) edit a new untitled macro
+//    -------------------------
+edit  // Must open TMPDIR/untitled.sci with the following (uncommented) content:
+// function [] = untitled()
+// endfunction
+
+
+// 2) edit a new macro with given name following functions naming rules
+//    -----------------------------------------------------------------
+clear abcdef
+edit abcdef  // Must open TMPDIR/abcdef.sci with the following (uncommented) content:
+// function [] = abcdef()
+// endfunction
+
+
+// 3) edit an existing file, while macroname does not follow macros naming rules (due to "/" and ".")
+//    --------------------------------------------------------------------------
+edit SCI/Version.incl  // Must open SCI/Version.incl
+
+
+// 4) edit a new file, while macroname does not follow macros naming rules (due to ".")
+//    ---------------------------------------------------------------------
+edit trials.sce   // Must ask for confirmation and then open trials.sce in the working directory
+
+
+// 5) edit a native macro directly
+//    ----------------------------
+clear factors
+edit factors  // Must open SCI/modules/polynomials/macros/factors.sci
+
+
+// 6) edit a native macro through an alias
+//    ------------------------------------
+sinus = sind
+edit sinus  // Must display a warning and open SCI/modules/elementary_functions/macros/sind.sci
+// --> edit sinus
+// WARNING: edit: "sinus" is an alias of "sind" => editing sind()
+// WARNING:       Please reset sinus=sind if sind() is recompiled.
+
+
+// 7) edit a native macro overwritten by a user-defined macro
+//    -------------------------------------------------------
+function r = factors(a)
+    disp("Actually my factors()")
+endfunction
+edit factors  // Must still open SCI/modules/polynomials/macros/factors.sci
+
+
+// 8) edit an existing user-defined function with no alias in libraries
+//    -----------------------------------------------------------------
+function r = my_test(w)
+  // heading comments
+  r = w+2
+endfunction
+edit my_test    // Must open TMPDIR/my_test.sci
+
+
+// 9) try to edit a primitive
+//    -----------------------
+clear sin
+edit sin     // Must display the following error:
+// --> edit sin
+// at line    78 of function edit ( SCI\modules\core\macros\edit.sci line 92 )
+// edit: sin() is an uneditable hard coded function.
+
+
+// 10) edit a native macro through an alias named after a primitive
+//     ------------------------------------------------------------
+sin = sind
+edit sin  // Must display a warning and open SCI/modules/elementary_functions/macros/sind.sci
+// --> edit sin
+// WARNING: edit: "sin" is an alias of "sind" => editing sind()
+// WARNING:       Please reset sin=sind if sind() is recompiled.
+
+
+// 11) edit a macro in a custom library, named as an existing primitive
+//     ----------------------------------------------------------------
+clear sin
+path = pathconvert("TMPDIR/editest");
+mkdir(path);
+mputl("function a = sin(a),a = a+%pi, endfunction", path+"sin.sci");
+genlib("sinlib", path);
+sinlib = lib(path);
+sinlib.sin(2);
+edit sin     // Must display the following error:
+// --> edit sin
+// at line    78 of function edit ( SCI\modules\core\macros\edit.sci line 92 )
+// edit: sin() is an uneditable hard coded function.
+//
+// NOTE: This could be improved by searching in loaded libraries
+rmdir(path, "s");