* Bug 15357 fixed: atomsGetInstalledPath() softer wrt name & version 94/20994/6
Samuel GOUGEON [Fri, 31 May 2019 23:50:37 +0000 (01:50 +0200)]
  http://bugzilla.scilab.org/15357

  new page (PDF): http://bugzilla.scilab.org/attachment.cgi?id=4964

  Please check that the unit tests are not OS-specific (unlikely).

Change-Id: I4603d655ba3aab8a6def668d30e640278949840a

scilab/CHANGES.md
scilab/modules/atoms/help/en_US/atomsGetInstalledPath.xml
scilab/modules/atoms/macros/atomsGetInstalledPath.sci
scilab/modules/atoms/tests/unit_tests/atomsGetInstalledPath.tst [new file with mode: 0644]
scilab/modules/helptools/data/pages/homepage-en_US.html

index eac759a..514902a 100644 (file)
@@ -189,7 +189,7 @@ Feature changes and additions
 * `perms` can now build and return only unique permutations, without duplicates.
 * Most of graphic objects can be moved interactively in opened figures.
 * `circshift` is introduced.
-
+* `atomsGetInstalledPath` is no longer sensitive to the case or completeness of the modules names. Providing the modules versions is now optional.
 
 Help pages:
 -----------
@@ -268,7 +268,7 @@ Bug Fixes
 * [#2694](https://bugzilla.scilab.org/2694): `bitget` did not accept positive integers of types int8, int16 or int32.
 * [#5824](https://bugzilla.scilab.org/5824): The `datafit` algorithm was not documented.
 * [#6070](https://bugzilla.scilab.org/6070): How to make multiscaled plots was not documented.
-* [#7293](http://bugzilla.scilab.org/show_bug.cgi?id=7293): There was no function to circularly shift components, rows, columns or subarrays of an array. `circshift` introduced.
+* [#7293](https://bugzilla.scilab.org/7293): There was no function to circularly shift components, rows, columns or subarrays of an array. `circshift` introduced.
 * [#7562](https://bugzilla.scilab.org/7562): `factorial` could use a huge memory amount even for a scalar argument.
 * [#7589](https://bugzilla.scilab.org/7589): There was no function computing the binomial coefficients.
 * [#7657](https://bugzilla.scilab.org/7657): `lstsize` was a duplicate of `size` and should be removed.
@@ -341,6 +341,7 @@ Bug Fixes
 * [#15309](https://bugzilla.scilab.org/15309): `eval` was a weak duplicate of `evstr`. It should be removed.
 * [#15321](https://bugzilla.scilab.org/15321): `lu` was leaking memory.
 * [#15350](https://bugzilla.scilab.org/15350): `ric_desc` should be merged into `riccati`.
+* [#15357](https://bugzilla.scilab.org/15357): `atomsGetInstalledPath` returned "" if the provided technical name differs only by the case, or is a fragment, or failed when the version is not provided.
 * [#15359](https://bugzilla.scilab.org/15359): `twinkle` was not able to blink several independent objects.
 * [#15360](https://bugzilla.scilab.org/15360): `numer` and `denom` were poor and duplicates of the `.num` and `.den` fields of rationals. They are removed.
 * [#15368](https://bugzilla.scilab.org/15368): `freson` silently returned frequencies not corresponding to a maximum, or returned [] instead of some still computable maxima frequencies.
@@ -468,7 +469,7 @@ Bug Fixes
 * [#16232](https://bugzilla.scilab.org/16232): `colorbar` did not support `$` in `colminmax`, standing for the number of colors in the current color map.
 * [#16234](https://bugzilla.scilab.org/16234): Airy functions were not available.
 * [#16242](https://bugzilla.scilab.org/16242): `loadmatfile` could not read Octave native text data files.
-* [#16244](http://bugzilla.scilab.org/show_bug.cgi?id=16244): `perms` could freeze the whole computer. It could not ignore duplicate permutations.
+* [#16244](https://bugzilla.scilab.org/16244): `perms` could freeze the whole computer. It could not ignore duplicate permutations.
 * [#16245](https://bugzilla.scilab.org/16245): `gsort` could not sort booleans.
 * [#16246](https://bugzilla.scilab.org/16246): `isvector` was broken for sparse matrices.
 * [#16257](https://bugzilla.scilab.org/16257): `blockdiag` implemented to replace `sysdiag`, improved and extended to strings.
index fed9774..76305ca 100644 (file)
@@ -2,8 +2,8 @@
 <!--
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2012 - Scilab Enterprises - Simon GARESTE <simon.gareste@scilab-enterprises.com>
- *
  * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ * Copyright (C) 2019 - 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.
           xmlns:scilab="http://www.scilab.org" xml:id="atomsGetInstalledPath" xml:lang="en">
     <refnamediv>
         <refname>atomsGetInstalledPath</refname>
-        <refpurpose>Get the install path of installed external modules</refpurpose>
+        <refpurpose>Gets the install path of some installed external modules</refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Syntax</title>
         <synopsis>
             paths = atomsGetInstalledPath(modules)
+            paths = atomsGetInstalledPath(modules, section)
         </synopsis>
     </refsynopsisdiv>
     <refsection>
@@ -33,7 +34,7 @@
             <varlistentry>
                 <term>modules</term>
                 <listitem>
-                    <para>mx2, mx3 Matrix of strings:</para>
+                    <para>m x 1, m x 2, or m x 3 Matrix of strings:</para>
                     <informaltable border="1">
                         <tr>
                             <td>
@@ -45,8 +46,7 @@
                             <td>
                                 Mandatory
                             </td>
-                            <td>
-                            </td>
+                            <td/>
                         </tr>
                         <tr>
                             <td>
                                 <emphasis role="strong">Version</emphasis>
                             </td>
                             <td>
-                                Mandatory
+                                Optional
+                            </td>
+                            <td>
+                                If this column is missing or this value is "", the first
+                                (and possibly only installed) version found is considered.
                             </td>
                         </tr>
                         <tr>
                                 Optional
                             </td>
                             <td>
-                                If this field is empty or is not present,
-                                the "all" section is used.
+                                If this column is missing or this value is "", the "all" section is
+                                used. Possible values are "user", "allusers", and "all".
                             </td>
                         </tr>
                     </informaltable>
                 </listitem>
             </varlistentry>
             <varlistentry>
+                <term>section</term>
+                <para>single string among "user", "allusers", "all". It is used ony if
+                    <varname>modules</varname> has less than 3 columns. It is equivalent to
+                    <literal>modules(:,3)=section</literal>.
+                </para>
+            </varlistentry>
+            <varlistentry>
                 <term>paths</term>
-                <para>the paths of the given modules</para>
+                <para>
+                    the paths of the given modules (starting with SCI or SCIHOME),
+                    or "" for any unfound module, such that always size(paths,1)==size(modules,1).
+                </para>
             </varlistentry>
         </variablelist>
     </refsection>
     <refsection>
         <title>Description</title>
         <para>
-            <literal>atomsGetInstalledPath</literal> returns the installation path of given external modules
+            <literal>atomsGetInstalledPath</literal> returns the installation path of given
+            external modules, or "" for any unfound module.
+        </para>
+        <para>
+            If no module with the given exact case-sensitive technical name is found among installed
+            modules, the search is rerun in a case-insensitive way. If still no match is found, the
+            search is rerun in a case-insensitive way considering the provided technical name
+            as a fragment of the true name. In case of
+        </para>
+        <para>
+            If for a <literal>modules(i,:)</literal> several matches are found, only the first one
+            is considered.
         </para>
     </refsection>
     <refsection>
         <title>Examples</title>
         <programlisting role="example"><![CDATA[
-atomsSetConfig("Verbose","True");
-atomsRepositoryAdd("http://scene1.test.atoms.scilab.org");
-atomsInstall(["toolbox_5","1.0"]);
-atomsGetInstalledPath(["toolbox_5","1.0"]);
-atomsRemove("toolbox_5");
+atomsInstall SCI/modules/atoms/tests/unit_tests/toolbox_7V6_1.0-1.bin.zip user
+
+atomsGetInstalledPath toolbox_7V6       // exact name,                  no version
+atomsGetInstalledPath ToolBox_7v6       // else: case-insensitive name, no version
+atomsGetInstalledPath TOOLBOX_7         // else: fragment of name,      no version
+atomsGetInstalledPath toolbox_7 allusers  // + wrong section => "" (not found)
+atomsGetInstalledPath toolbox_7 all
+atomsGetInstalledPath(["toolbox_7", "2"])   // not this version => "" (not found)
+atomsGetInstalledPath(["toolbox_7", "1"])   // not this version => "" (not found)
+atomsGetInstalledPath(["toolbox_7", "1.0"]) // version found
+
+atomsRemove("toolbox_7V6");
  ]]></programlisting>
     </refsection>
     <refsection role="see also">
         <title>See also</title>
         <simplelist type="inline">
             <member>
-                <link linkend="atomsInstall">atomsInstall</link>
+                <link linkend="atomsGetLoadedPath">atomsGetLoadedPath</link>
             </member>
             <member>
-                <link linkend="atomsIsInstalled">atomsIsInstalled</link>
+                <link linkend="atomsGetLoaded">atomsGetLoaded</link>
+            </member>
+            <member>
+                <link linkend="atomsGetInstalled">atomsGetInstalled</link>
+            </member>
+            <member>
+                <link linkend="atomsAutoloadList">atomsAutoloadList</link>
             </member>
         </simplelist>
     </refsection>
+    <refsection role="history">
+        <title>History</title>
+        <revhistory>
+            <revision>
+                <revnumber>6.1.0</revnumber>
+                <revdescription>
+                    <itemizedlist>
+                        <listitem>
+                            The technical name can now be case-insensitive, or a case-insensitive
+                            fragment of the full true technical name of each searched module.
+                        </listitem>
+                        <listitem>
+                            The version is now optional (use "" to accept any version).
+                        </listitem>
+                    </itemizedlist>
+                </revdescription>
+            </revision>
+        </revhistory>
+    </refsection>
 </refentry>
index 54fb335..bef78b7 100644 (file)
@@ -1,7 +1,7 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) 2009 - DIGITEO - Pierre MARECHAL <pierre.marechal@scilab.org>
-//
 // Copyright (C) 2012 - 2016 - Scilab Enterprises
+// Copyright (C) 2019 - 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.
 // For more information, see the COPYING file which you should have received
 // along with this program.
 
-// Internal function
-
-// Add an URL to the list of repositories, and returns
-
 function res = atomsGetInstalledPath(packages,section)
 
     rhs           = argn(2);
@@ -34,95 +30,97 @@ function res = atomsGetInstalledPath(packages,section)
         error(msprintf(gettext("%s: Wrong type for input argument #%d: string expected.\n"),"atomsGetInstalledPath",1));
     end
 
-    if and(size(packages(1,:),"*") <> [2 3]) then
-        error(msprintf(gettext("%s: Wrong size for input argument #%d: mx2 or mx3 string matrix expected.\n"),"atomsGetInstalledPath",1));
+    if and(size(packages, 2) <> [1 2 3]) then
+        error(msprintf(gettext("%s: Argument #%d: Matrix with %s columns expected.\n"),"atomsGetInstalledPath",1, _("1 to 3")));
     end
 
     packages = stripblanks(packages);
 
-    if or(packages(:,2)=="")  then
-        error(msprintf(gettext("%s: Wrong value for input argument #%d: All modules version should be set.\n"),"atomsGetInstalledPath",1));
+    if size(packages,2)==1 then
+        packages = [packages emptystr(packages)]
     end
 
-    packages = stripblanks(packages);
-
     // Allusers/user management
     // =========================================================================
-
-    if rhs < 2 then
-        section = "all";
-
-    else
-
-        // Process the 2nd input argument : section
-        // Allusers can be equal to "user" or "allusers"
-
-        if type(section) <> 10 then
-            error(msprintf(gettext("%s: Wrong type for input argument #%d: Boolean or single string expected.\n"),"atomsGetInstalledPath",2));
+    if size(packages, 2) < 3 then
+        if rhs < 2 then
+            section = "all";
+        else
+            // Process the 2nd input argument : section
+            // Allusers can be equal to "user" or "allusers"
+            if type(section) <> 10 then
+                error(msprintf(gettext("%s: Wrong type for input argument #%d: string expected.\n"),"atomsGetInstalledPath",2));
+            end
+            section = section(1)
+            if and(section <> ["user","allusers","all"]) then
+                error(msprintf(gettext("%s: Wrong value for input argument #%d: ''user'' or ''allusers'' or ''all'' expected.\n"),"atomsGetInstalledPath",2));
+            end
         end
-
-        if (type(section) == 10) & and(section<>["user","allusers","all"]) then
-            error(msprintf(gettext("%s: Wrong value for input argument #%d: ''user'' or ''allusers'' or ''all'' expected.\n"),"atomsGetInstalledPath",2));
+        packages = [packages emptystr(packages(:,1)) + section]
+    else
+        tmp = convstr(packages(:,3))
+        if or(tmp<>"user" & tmp<>"allusers" & tmp<>"all")
+            error(msprintf(gettext("%s: Argument #%d (:,3): ''user'' or ''allusers'' or ''all'' expected.\n"),"atomsGetInstalledPath",1));
         end
-
-    end
-
-    // Complete packages matrix with empty columns
-    // =========================================================================
-
-    if size(packages(1,:),"*") == 2 then
-        packages = [ packages emptystr(size(packages(:,1),"*"),1) ];
+        packages(:,3) = tmp
+        section = "all"
     end
 
     // Get the list of installed packages
     // =========================================================================
     installedpackages = atomsGetInstalled(section);
+    names = convstr(installedpackages(:,1));    // for case-insensitive detection
 
     // Loop on name
     // =========================================================================
 
-    for i=1:size(packages(:,1),"*")
+    for i = 1:size(packages,1)
 
         // Filter on names
-        packages_filtered = installedpackages( find(installedpackages(:,1) == packages(i,1)) , : );
-
-        if packages_filtered == [] then
+        found = find(installedpackages(:,1) == packages(i,1))
+        if found == []
+            // Try in a case-insensitive way
+            found = find(names == convstr(packages(i,1)))
+        end
+        if found == []
+            // Try with input as a case-insensitive fragment
+            found = grep(names, convstr(packages(i,1)))
+        end
+        if found == []
             res(i) = "";
             continue;
         end
+        packages_filtered = installedpackages(found, : );
 
         // Filter on section
-        if ~isempty(packages(i,3)) & packages(i,3)<>"all" then
+        if packages(i,3) <> "all" then
             packages_filtered = packages_filtered( find(packages_filtered(:,3) == packages(i,3)) , : );
         end
 
         // Filter on versions
-
         //  + The packaging version is mentioned
-        if ~ isempty(strindex(packages(i,2),"-")) then
-            packages_filtered = packages_filtered( find(packages_filtered(:,2) == packages(i,2)) , : );
-
-            //  + The packaging version is not mentioned
-        else
-
-            candidates        = packages_filtered;
-            packages_filtered = [];
-
-            // Loop on installed versions
-            for j=1:size(candidates(:,2),"*")
-
-                candidate_version = candidates(j,2);
-
-                if ~ isempty(strindex(candidate_version,"-")) then
-                    candidate_version = part(candidate_version,1:strindex(candidate_version,"-")-1);
-                end
-
-                if packages(i,2) == candidate_version then
-                    packages_filtered = [ packages_filtered ; candidates(j,:) ];
+        if packages_filtered <> [] & packages(i,2) <> ""
+            if ~ isempty(strindex(packages(i,2),"-")) then
+                packages_filtered = packages_filtered( find(packages_filtered(:,2) == packages(i,2)) , : );
+            else
+                //  + The packaging version is not mentioned
+                candidates        = packages_filtered;
+                packages_filtered = [];
+    
+                // Loop on installed versions
+                for j=1:size(candidates(:,2),"*")
+    
+                    candidate_version = candidates(j,2);
+    
+                    if ~ isempty(strindex(candidate_version,"-")) then
+                        candidate_version = part(candidate_version,1:strindex(candidate_version,"-")-1);
+                    end
+    
+                    if packages(i,2) == candidate_version then
+                        packages_filtered = [ packages_filtered ; candidates(j,:) ];
+                    end
                 end
-
             end
-
         end
 
         if packages_filtered == [] then
@@ -130,12 +128,10 @@ function res = atomsGetInstalledPath(packages,section)
             continue;
         end
 
-        if ~ isempty(packages_filtered) then
+        if ~isempty(packages_filtered) then
             res(i) = packages_filtered(1,4);
         else
             res(i) = "";
         end
-
     end
-
 endfunction
diff --git a/scilab/modules/atoms/tests/unit_tests/atomsGetInstalledPath.tst b/scilab/modules/atoms/tests/unit_tests/atomsGetInstalledPath.tst
new file mode 100644 (file)
index 0000000..cf4c74a
--- /dev/null
@@ -0,0 +1,46 @@
+// ============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2019 - 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.
+// ============================================================================
+//
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// unit tests for atomsGetInstalledPath()
+
+offlineStatus = atomsGetConfig("offline");
+atomsSetConfig("offline","True");
+atomsInstall("SCI/modules/atoms/tests/unit_tests/toolbox_7V6_1.0-1.bin.zip", "user");
+
+if getos() == "Windows" then
+    ref = pathconvert("SCIHOME\atoms\x64\toolbox_7V6\1.0", %f, %f);
+else
+    ref = pathconvert("SCIHOME\atoms\toolbox_7V6\1.0", %f, %f);
+end
+
+p = atomsGetInstalledPath("toolbox_7V6");   // exact technical name
+assert_checkequal(p, ref);
+p = atomsGetInstalledPath("ToolBox_7v6");   // else: case-insensitive one
+assert_checkequal(p, ref);
+p = atomsGetInstalledPath("TOOLBOX_7");     // else: case-insensitive fragment
+assert_checkequal(p, ref);
+p = atomsGetInstalledPath("toolbox_7", "all");
+assert_checkequal(p, ref);
+p = atomsGetInstalledPath("toolbox_7", "allusers");
+assert_checkequal(p, "");                         // wrong section
+p = atomsGetInstalledPath(["toolbox_7","2"]);   // wrong version
+assert_checkequal(p, "");
+p = atomsGetInstalledPath(["toolbox_7","1"]);   // wrong version
+assert_checkequal(p, "");
+p = atomsGetInstalledPath(["toolbox_7","1.0"]); // version found
+assert_checkequal(p, ref);
+
+atomsRemove("toolbox_7V6","user");
+atomsSetConfig("offline", offlineStatus);
index 2934032..64bd0d0 100644 (file)
             </li>
             <li><code>nchoosek</code> is introduced, to compute the binomial coefficients.</li>
             <li>The left .\. and right ./. Kronecker divisions are now implemented, for arrays of decimal or complex numbers.</li>
+            <li><code>perms</code> can now build and return only unique permutations, without duplicates.</li>
+            <li>Most of graphic objects can be moved interactively in opened figures.</li>
+            <li><code>circshift</code> is introduced.</li>
+            <li><code>atomsGetInstalledPath</code> is no longer sensitive to the case or completeness of the modules names. Providing the modules versions is now optional.</li>
         </ul>
         <h2 class="title">Help pages</h2>
         <ul>