* Bug 15898 fixed: edit() with user-defined | alias of macro
[scilab.git] / scilab / modules / scinotes / macros / edit.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) ????-2008 - INRIA
3 // Copyright (C) 2008 - INRIA - Allan CORNET
4 // Copyright (C) 2010 - DIGITEO - Allan CORNET
5 // Copyright (C) 2012 - 2016 - Scilab Enterprises
6 // Copyright (C) 2018 - Samuel GOUGEON
7 //
8 // This file is hereby licensed under the terms of the GNU GPL v2.0,
9 // pursuant to article 5.3.4 of the CeCILL v.2.1.
10 // This file was originally licensed under the terms of the CeCILL v2.1,
11 // and continues to be available under such terms.
12 // For more information, see the COPYING file which you should have received
13 // along with this program.
14
15 function edit(macroname, linenumber)
16     // macroname : character string giving a macroname
17     // linenumber : line number
18
19     [lhs,rhs] = argn(0);
20     if (rhs > 2) then
21         error(sprintf(gettext("%s: Wrong number of input argument(s): At least %d expected.\n"), "edit", 1));
22     end
23
24     if (rhs >= 1 & type(macroname) ~= 10) then
25         error(sprintf(gettext("%s: Wrong type for input argument #%d: String expected.\n"),"edit",1));
26     end
27
28     if (rhs == 2 & type(linenumber) ~= 1) then
29         error(msprintf(gettext("%s: Wrong type for input argument #%d: Double expected.\n"),"edit",2));
30     end
31
32     found = %f;
33     tmp = %f;
34     // tmpdir will have trailing / or \
35     tmpdir= pathconvert(TMPDIR);
36
37     if rhs >= 1 then // macroname or filename is given
38         if regexp(macroname, "/^([a-zA-Z%_#!$?][0-9a-zA-Z_#!$?]*)$/") == [] then
39             // File
40             fname = macroname;
41             found = %t;
42         else
43             if isdef(macroname)
44                 execstr("object = "+macroname)
45                 if type(object)==13
46                     // macroname may be an alias. Example: sinus = sind
47                     // We need to get the original macro name to edit it:
48                     tree = macr2tree(object);
49                     tmp = tree.name
50                     if tmp ~= macroname then
51                         msg = _("edit: ""%s"" is an alias of ""%s"" => editing %s()\n      Please reset %s=%s if %s() is recompiled.\n")
52                         warning(msprintf(msg, macroname, tmp, tmp, macroname, tmp, tmp))
53                         macroname = tmp
54                     end
55
56                     libr = whereis(macroname);
57                     if type(libr($))==10 & libr($)=="script"
58                         // the user-defined macro may overwrite a macro in library
59                         path = whereis_in_libs(macroname)
60                         if path ~= []
61                             // priority = from library:
62                             fname = pathconvert(path) + macroname + ".sci"
63                         else
64                             txt = tree2code(tree, %t);
65                             fname = tmpdir + macroname + ".sci";
66                             mputl(txt, fname);
67                         end
68                         found = %t
69                     else // libr is either a module name or a library name
70                         libr = libr($)
71                         err = execstr("tmp="+libr, "errcatch")
72                         if ~err & type(tmp)==14
73                             [macrolist, path] = libraryinfo(libr);
74                             fname = pathconvert(path) + macroname + ".sci"
75                             found = %t
76                         else // either a module name or any variable name:
77                             // If macroname is a user-defined function,
78                             // whereis() would have reported it as "script".
79                             // => it's a macro in a library, but with a
80                             // macroname equal to a built-in name
81                             // => we must retrieve the library without whereis()
82                             path = whereis_in_libs(macroname)
83                             if path ~= []
84                                 fname = pathconvert(path) + macroname + ".sci"
85                                 found = %t
86                             end
87                         end
88                     end
89                 end
90
91                 if ~found & funptr(macroname)<>0 then
92                     error(msprintf(gettext("%s: %s() is an uneditable hard coded function.\n"), "edit", macroname));
93                 end
94             end
95         end
96     end
97
98     if ~found
99         if ~isdef("macroname","l")
100             macroname = "untitled"
101         end
102         fname = tmpdir + macroname + ".sci";
103         txt = ["function [] = " + macroname + "()"; "endfunction"];
104         mputl(txt, fname);
105     end
106
107     // call the editor with the filename
108     if (rhs == 2) then
109         editor(fname, linenumber, macroname);
110     else
111         editor(fname);
112     end
113
114 endfunction
115
116 // ----------------------------------------------------------------------------
117
118 function path = whereis_in_libs(macroname)
119     path = []
120     for l = librarieslist()'
121         [m, p] = libraryinfo(l)
122         if or(m==macroname)
123             path = p
124             break
125         end
126     end
127 endfunction