summaryrefslogtreecommitdiffstats
path: root/scilab/modules
diff options
context:
space:
mode:
authormottelet <stephane.mottelet@utc.fr>2021-02-05 15:23:04 +0100
committerClément David <clement.david@esi-group.com>2021-04-01 12:00:48 +0200
commit92f54c2a9ba77a9e2f34b9c36f320a2baf5b78a5 (patch)
tree09293abf890622e460c77095315f9df648cd0228 /scilab/modules
parent1e737dd2260acfbf1c71fef8307b9e46c99055a8 (diff)
downloadscilab-92f54c2a9ba77a9e2f34b9c36f320a2baf5b78a5.zip
scilab-92f54c2a9ba77a9e2f34b9c36f320a2baf5b78a5.tar.gz
[fileio] allow mopen and mclose to handle multiple files
It would allow files = listfiles("*.sce"); hash(mopen(files),"sha256") if https://codereview.scilab.org/#/c/21697/ is merged, as hash() already handles arrays of file descriptors. Change-Id: I03e0224f66446f893336ccbe7569e01e460da119
Diffstat (limited to 'scilab/modules')
-rw-r--r--scilab/modules/fileio/help/en_US/mclose.xml21
-rw-r--r--scilab/modules/fileio/help/en_US/mopen.xml18
-rw-r--r--scilab/modules/fileio/sci_gateway/cpp/sci_mclose.cpp86
-rw-r--r--scilab/modules/fileio/sci_gateway/cpp/sci_mopen.cpp85
-rw-r--r--scilab/modules/fileio/tests/unit_tests/mclose.tst18
-rw-r--r--scilab/modules/fileio/tests/unit_tests/mopen.tst19
6 files changed, 146 insertions, 101 deletions
diff --git a/scilab/modules/fileio/help/en_US/mclose.xml b/scilab/modules/fileio/help/en_US/mclose.xml
index 1209432..a9044c4 100644
--- a/scilab/modules/fileio/help/en_US/mclose.xml
+++ b/scilab/modules/fileio/help/en_US/mclose.xml
@@ -17,12 +17,13 @@
17<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="en" xml:id="mclose"> 17<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="en" xml:id="mclose">
18 <refnamediv> 18 <refnamediv>
19 <refname>mclose</refname> 19 <refname>mclose</refname>
20 <refpurpose>closes an opened file</refpurpose> 20 <refpurpose>closes opened files</refpurpose>
21 </refnamediv> 21 </refnamediv>
22 <refsynopsisdiv> 22 <refsynopsisdiv>
23 <title>Syntax</title> 23 <title>Syntax</title>
24 <synopsis> 24 <synopsis>
25 err = mclose([fd]) 25 err = mclose(fd)
26 err = mclose(paths)
26 mclose('all') 27 mclose('all')
27 </synopsis> 28 </synopsis>
28 </refsynopsisdiv> 29 </refsynopsisdiv>
@@ -33,14 +34,22 @@
33 <term>fd</term> 34 <term>fd</term>
34 <listitem> 35 <listitem>
35 <para> 36 <para>
36 a scalar: the <varname>fd</varname> parameter returned by the function <function>mopen</function> is used as a file descriptor. 37 a matrix of integers: the <varname>fd</varname> matrix returned by the function <function>mopen</function> is used as a matrix of file descriptors.
38 </para>
39 </listitem>
40 </varlistentry>
41 <varlistentry>
42 <term>paths</term>
43 <listitem>
44 <para>
45 a matrix of strings: the absolute paths of files to be closed.
37 </para> 46 </para>
38 </listitem> 47 </listitem>
39 </varlistentry> 48 </varlistentry>
40 <varlistentry> 49 <varlistentry>
41 <term>err</term> 50 <term>err</term>
42 <listitem> 51 <listitem>
43 <para>a scalar: an error indicator.</para> 52 <para>a matrix of integers: error indicators.</para>
44 </listitem> 53 </listitem>
45 </varlistentry> 54 </varlistentry>
46 </variablelist> 55 </variablelist>
@@ -48,9 +57,9 @@
48 <refsection> 57 <refsection>
49 <title>Description</title> 58 <title>Description</title>
50 <para> 59 <para>
51 <function>mclose</function> must be used to close a file opened by 60 <function>mclose</function> must be used to close files opened by
52 <function>mopen</function>. If <varname>fd</varname> is omitted 61 <function>mopen</function>. If <varname>fd</varname> is omitted
53 <function>mclose</function> closes the last opend file. 62 <function>mclose</function> closes the last opened file.
54 </para> 63 </para>
55 <para> 64 <para>
56 <code>mclose('all')</code> closes all files opened by 65 <code>mclose('all')</code> closes all files opened by
diff --git a/scilab/modules/fileio/help/en_US/mopen.xml b/scilab/modules/fileio/help/en_US/mopen.xml
index 7c08db1..54481fd 100644
--- a/scilab/modules/fileio/help/en_US/mopen.xml
+++ b/scilab/modules/fileio/help/en_US/mopen.xml
@@ -17,25 +17,25 @@
17<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns4="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="mopen" xml:lang="en"> 17<refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns4="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="mopen" xml:lang="en">
18 <refnamediv> 18 <refnamediv>
19 <refname>mopen</refname> 19 <refname>mopen</refname>
20 <refpurpose>opens a file in Scilab</refpurpose> 20 <refpurpose>opens files in Scilab</refpurpose>
21 </refnamediv> 21 </refnamediv>
22 <refsynopsisdiv> 22 <refsynopsisdiv>
23 <title>Syntax</title> 23 <title>Syntax</title>
24 <synopsis>[fd, err] = mopen(file [, mode, swap ])</synopsis> 24 <synopsis>[fd, err] = mopen(files [, mode, swap ])</synopsis>
25 </refsynopsisdiv> 25 </refsynopsisdiv>
26 <refsection> 26 <refsection>
27 <title>Arguments</title> 27 <title>Arguments</title>
28 <variablelist> 28 <variablelist>
29 <varlistentry> 29 <varlistentry>
30 <term>file</term> 30 <term>files</term>
31 <listitem> 31 <listitem>
32 <para>a character string containing the path of the file to open.</para> 32 <para>a matrix of strings containing the paths of the files to open.</para>
33 </listitem> 33 </listitem>
34 </varlistentry> 34 </varlistentry>
35 <varlistentry> 35 <varlistentry>
36 <term>mode</term> 36 <term>mode</term>
37 <listitem> 37 <listitem>
38 <para>a character string specifying the access mode requested for the file.</para> 38 <para>a string specifying the access mode requested for the files.</para>
39 </listitem> 39 </listitem>
40 </varlistentry> 40 </varlistentry>
41 <varlistentry> 41 <varlistentry>
@@ -52,7 +52,7 @@
52 <varlistentry> 52 <varlistentry>
53 <term>err</term> 53 <term>err</term>
54 <listitem> 54 <listitem>
55 <para>a scalar. Error indicator.</para> 55 <para>a matrix of integers. Error indicators.</para>
56 <informaltable border="1"> 56 <informaltable border="1">
57 <tr> 57 <tr>
58 <td>error value:</td> 58 <td>error value:</td>
@@ -89,7 +89,7 @@
89 <term>fd</term> 89 <term>fd</term>
90 <listitem> 90 <listitem>
91 <para> 91 <para>
92 a scalar: a file descriptor (it's a positive integer). 92 a matrix of file descriptors (they are positive integers).
93 </para> 93 </para>
94 </listitem> 94 </listitem>
95 </varlistentry> 95 </varlistentry>
@@ -98,9 +98,9 @@
98 <refsection> 98 <refsection>
99 <title>Description</title> 99 <title>Description</title>
100 <para> 100 <para>
101 <function>mopen</function> may be used to open a <varname>file</varname> in a way 101 <function>mopen</function> may be used to open <varname>files</varname> in a way
102 compatible with the C <function>fopen</function> procedure. Without 102 compatible with the C <function>fopen</function> procedure. Without
103 <varname>swap</varname> argument the <varname>file</varname> is supposed to be coded in "little endian IEEE 103 <varname>swap</varname> argument the <varname>files</varname> are supposed to be coded in "little endian IEEE
104 format" and data are swapped if necessary to match the IEEE format of 104 format" and data are swapped if necessary to match the IEEE format of
105 the processor. 105 the processor.
106 </para> 106 </para>
diff --git a/scilab/modules/fileio/sci_gateway/cpp/sci_mclose.cpp b/scilab/modules/fileio/sci_gateway/cpp/sci_mclose.cpp
index c802d54..d1372b0 100644
--- a/scilab/modules/fileio/sci_gateway/cpp/sci_mclose.cpp
+++ b/scilab/modules/fileio/sci_gateway/cpp/sci_mclose.cpp
@@ -1,8 +1,8 @@
1/* 1/*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab 2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2010-2010 - DIGITEO - Antoine ELIAS 3 * Copyright (C) 2010-2010 - DIGITEO - Antoine ELIAS
4 * 4 * Copyright (C) 2012 - 2016 - Scilab Enterprises
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises 5 * Copyright (C) 2021 - Stéphane MOTTELET
6 * 6 *
7 * This file is hereby licensed under the terms of the GNU GPL v2.0, 7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1. 8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
@@ -26,69 +26,84 @@ extern "C"
26#include "localization.h" 26#include "localization.h"
27#include "mclose.h" 27#include "mclose.h"
28#include "os_string.h" 28#include "os_string.h"
29#include "sciprint.h"
29} 30}
30#include "stdio.h"
31 31
32types::Function::ReturnValue sci_mclose(types::typed_list &in, int _iRetCount, types::typed_list &out) 32types::Function::ReturnValue sci_mclose(types::typed_list &in, int _iRetCount, types::typed_list &out)
33{ 33{
34 types::Double* pDblRet;
34 int iRet = 0; 35 int iRet = 0;
36
35 if (in.size() == 0) 37 if (in.size() == 0)
36 { 38 {
37 //close current file 39 //close current file
38 iRet = mcloseCurrentFile(); 40 iRet = mcloseCurrentFile();
41 pDblRet = new types::Double(static_cast<double>(iRet));
39 } 42 }
40 else if (in.size() == 1) 43 else if (in.size() == 1)
41 { 44 {
42 if (in[0]->isString()) 45 if (in[0]->isString())
43 { 46 {
44 types::String *pS = in[0]->getAs<types::String>(); 47 types::String *pS = in[0]->getAs<types::String>();
45 if (pS->getSize() != 1) 48 pDblRet = new types::Double(pS->getDims(),pS->getDimsArray());
46 { 49 pDblRet->setZeros();
47 Scierror(999, _("%s: Wrong type for input argument #%d: A String expected.\n"), "mclose", 1);
48 return types::Function::Error;
49 }
50 50
51 if (FileManager::isOpened(pS->get(0))) 51 if (pS->getSize()==1 && os_wcsicmp(pS->get(0), L"all") == 0)
52 {
53 int iFileID = FileManager::getFileID(pS->get(0));
54 if (iFileID == -1)
55 {
56 char* pst = wide_string_to_UTF8(pS->get(0));
57 Scierror(999, _("%s: File not found: '%s'.\n"), "mclose", pst);
58 FREE(pst);
59 return types::Function::Error;
60 }
61 iRet = mclose(iFileID);
62 }
63 else if (os_wcsicmp(pS->get(0), L"all") == 0)
64 { 52 {
65 iRet = mcloseAll(); 53 iRet = mcloseAll();
54 pDblRet->set(0,static_cast<double>(iRet));
66 } 55 }
67 else 56 else
68 { 57 {
69 Scierror(999, _("%s: Wrong input arguments: '%s' expected.\n"), "mclose", "all"); 58 for (int i=0; i < pS->getSize(); i++)
70 return types::Function::Error; 59 {
60 if (FileManager::isOpened(pS->get(i)))
61 {
62 int iFileID = FileManager::getFileID(pS->get(i));
63 if (iFileID == -1)
64 {
65 char* pst = wide_string_to_UTF8(pS->get(i));
66 Scierror(999, _("%s: File not found: '%s'.\n"), "mclose", pst);
67 FREE(pst);
68 pDblRet->killMe();
69 return types::Function::Error;
70 }
71 iRet = mclose(iFileID);
72 pDblRet->set(i,static_cast<double>(iRet));
73 } else {
74 sciprint(_("%s: Cannot close file %ls: File is not active.\n"), "mclose", pS->get(i));
75 }
76 }
71 } 77 }
72 } 78 }
73 else if (in[0]->isDouble()) 79 else if (in[0]->isDouble())
74 { 80 {
75 types::Double* pD = in[0]->getAs<types::Double>(); 81 types::Double* pDblIn = in[0]->getAs<types::Double>();
76 if (pD->getSize() != 1 || pD->isComplex()) 82
83 if (pDblIn->isComplex())
77 { 84 {
78 Scierror(999, _("%s: Wrong type for input argument #%d: A real expected.\n"), "mclose", 1); 85 Scierror(999, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), "mclose", 1);
79 return types::Function::Error; 86 return types::Function::Error;
80 } 87 }
81 88
82 int iVal = static_cast<int>(pD->get(0)); 89 pDblRet = new types::Double(pDblIn->getDims(),pDblIn->getDimsArray());
83 switch (iVal) 90 pDblRet->setZeros();
91
92 for (int i=0; i < pDblIn->getSize(); i++)
84 { 93 {
85 case 0: // stderr 94 int iVal = static_cast<int>(pDblIn->get(i));
86 case 5: // stdin 95 switch (iVal)
87 case 6: // stdout 96 {
88 Scierror(999, _("%s: Wrong file descriptor: %d.\n"), "mclose", iVal); 97 case 0: // stderr
89 return types::Function::Error; 98 case 5: // stdin
99 case 6: // stdout
100 Scierror(999, _("%s: Wrong file descriptor: %d.\n"), "mclose", iVal);
101 pDblRet->killMe();
102 return types::Function::Error;
103 }
104 iRet = mclose(iVal);
105 pDblRet->set(i,static_cast<double>(iRet));
90 } 106 }
91 iRet = mclose(iVal);
92 } 107 }
93 else 108 else
94 { 109 {
@@ -102,8 +117,7 @@ types::Function::ReturnValue sci_mclose(types::typed_list &in, int _iRetCount, t
102 return types::Function::Error; 117 return types::Function::Error;
103 } 118 }
104 119
105 types::Double* pD = new types::Double(static_cast<double>(iRet)); 120 out.push_back(pDblRet);
106 out.push_back(pD);
107 return types::Function::OK; 121 return types::Function::OK;
108} 122}
109/*--------------------------------------------------------------------------*/ 123/*--------------------------------------------------------------------------*/
diff --git a/scilab/modules/fileio/sci_gateway/cpp/sci_mopen.cpp b/scilab/modules/fileio/sci_gateway/cpp/sci_mopen.cpp
index 8043344..8305c17 100644
--- a/scilab/modules/fileio/sci_gateway/cpp/sci_mopen.cpp
+++ b/scilab/modules/fileio/sci_gateway/cpp/sci_mopen.cpp
@@ -56,15 +56,6 @@ types::Function::ReturnValue sci_mopen(types::typed_list &in, int _iRetCount, ty
56 return types::Function::Error; 56 return types::Function::Error;
57 } 57 }
58 58
59 types::String* pS1 = in[0]->getAs<types::String>();
60 if (pS1->getSize() != 1)
61 {
62 Scierror(999, _("%s: Wrong size for input argument #%d: string expected.\n"), "mopen", 1);
63 return types::Function::Error;
64 }
65
66 pstFilename = expandPathVariableW(pS1->get(0));
67
68 if (in.size() >= 2) 59 if (in.size() >= 2)
69 { 60 {
70 //mode 61 //mode
@@ -125,55 +116,61 @@ types::Function::ReturnValue sci_mopen(types::typed_list &in, int _iRetCount, ty
125 return types::Function::Error; 116 return types::Function::Error;
126 } 117 }
127 118
128 wchar_t* pwstTemp = get_full_pathW(pstFilename); 119 types::String* pS1 = in[0]->getAs<types::String>();
129 iErr = mopen(pwstTemp, pstMode, iSwap, &iID); 120 types::Double* pD = new types::Double(pS1->getRows(),pS1->getCols());
130 if (iErr != MOPEN_NO_ERROR) 121 types::Double* pD2 = new types::Double(pS1->getRows(),pS1->getCols());
122
123 for (int i=0; i<pS1->getSize(); i++)
131 { 124 {
132 //mange file open errors 125 pstFilename = expandPathVariableW(pS1->get(i));
133 if (_iRetCount <= 1) 126 wchar_t* pwstTemp = get_full_pathW(pstFilename);
127 iErr = mopen(pwstTemp, pstMode, iSwap, &iID);
128
129 if (iErr != MOPEN_NO_ERROR)
134 { 130 {
135 switch (iErr) 131 //mange file open errors
132 if (_iRetCount <= 1)
136 { 133 {
137 case MOPEN_CAN_NOT_OPEN_FILE: 134 switch (iErr)
138 { 135 {
139 char* pst = wide_string_to_UTF8(pstFilename); 136 case MOPEN_CAN_NOT_OPEN_FILE:
140 Scierror(999, _("%s: Cannot open file %s.\n"), "mopen", pst); 137 {
141 FREE(pst); 138 char* pst = wide_string_to_UTF8(pstFilename);
142 FREE(pstFilename); 139 Scierror(999, _("%s: Cannot open file %s.\n"), "mopen", pst);
143 FREE(pwstTemp); 140 FREE(pst);
144 pstFilename = NULL; 141 }
145 return types::Function::Error; 142 case MOPEN_INVALID_FILENAME:
146 } 143 {
147 case MOPEN_INVALID_FILENAME: 144 Scierror(999, _("%s: invalid filename.\n"), "mopen");
148 { 145 }
149 Scierror(999, _("%s: invalid filename.\n"), "mopen"); 146 case MOPEN_INVALID_STATUS:
150 FREE(pstFilename); 147 {
151 FREE(pwstTemp); 148 Scierror(999, _("%s: invalid status.\n"), "mopen");
152 pstFilename = NULL; 149 }
153 return types::Function::Error;
154 }
155 case MOPEN_INVALID_STATUS:
156 {
157 Scierror(999, _("%s: invalid status.\n"), "mopen");
158 FREE(pstFilename);
159 FREE(pwstTemp);
160 pstFilename = NULL;
161 return types::Function::Error;
162 } 150 }
151 FREE(pstFilename);
152 FREE(pwstTemp);
153 pD->killMe();
154 pD2->killMe();
155 return types::Function::Error;
163 } 156 }
164 } 157 }
165 }
166 158
167 FREE(pwstTemp); 159 FREE(pwstTemp);
168 FREE(pstFilename); 160 FREE(pstFilename);
161 pD->set(i,static_cast<double>(iID));
162 pD2->set(i,static_cast<double>(iErr));
163 }
169 164
170 types::Double* pD = new types::Double(static_cast<double>(iID));
171 out.push_back(pD); 165 out.push_back(pD);
172 166
173 if (_iRetCount == 2) 167 if (_iRetCount == 2)
174 { 168 {
175 types::Double* pD2 = new types::Double(iErr);
176 out.push_back(pD2); 169 out.push_back(pD2);
177 } 170 }
171 else
172 {
173 pD2->killMe();
174 }
178 return types::Function::OK; 175 return types::Function::OK;
179} 176}
diff --git a/scilab/modules/fileio/tests/unit_tests/mclose.tst b/scilab/modules/fileio/tests/unit_tests/mclose.tst
index 0cc2a8b..ebfbcd6 100644
--- a/scilab/modules/fileio/tests/unit_tests/mclose.tst
+++ b/scilab/modules/fileio/tests/unit_tests/mclose.tst
@@ -8,14 +8,20 @@
8 8
9// <-- CLI SHELL MODE --> 9// <-- CLI SHELL MODE -->
10 10
11fd = mopen(TMPDIR + filesep() + 'mclose_tst','wt'); 11fd(1) = mopen(TMPDIR + filesep() + 'mclose_tst_1','wt');
12mclose(TMPDIR + filesep() + 'mclose_tst'); 12fd(2) = mopen(TMPDIR + filesep() + 'mclose_tst_2','wt');
13 13
14ierr = execstr('mclose([''file1'',''file2''])','errcatch'); 14mclose(fd);
15if ierr <> 999 then pause,end
16 15
17ierr = execstr('mclose([1,2])','errcatch'); 16mopen(TMPDIR + filesep() + 'mclose_tst_1','wt');
18if ierr <> 999 then pause,end 17mopen(TMPDIR + filesep() + 'mclose_tst_2','wt');
18
19mclose(TMPDIR + filesep() + ['mclose_tst_1','mclose_tst_2']);
20
21mopen(TMPDIR + filesep() + 'mclose_tst_1','wt');
22mopen(TMPDIR + filesep() + 'mclose_tst_2','wt');
23
24mclose("all")
19 25
20ierr = execstr('mclose(0)','errcatch'); 26ierr = execstr('mclose(0)','errcatch');
21if ierr <> 999 then pause,end 27if ierr <> 999 then pause,end
diff --git a/scilab/modules/fileio/tests/unit_tests/mopen.tst b/scilab/modules/fileio/tests/unit_tests/mopen.tst
new file mode 100644
index 0000000..3ec0a5d
--- /dev/null
+++ b/scilab/modules/fileio/tests/unit_tests/mopen.tst
@@ -0,0 +1,19 @@
1// =============================================================================
2// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3// Copyright (C) 2021 - Stéphane MOTTELET
4//
5// This file is distributed under the same license as the Scilab package.
6// =============================================================================
7
8// <-- CLI SHELL MODE -->
9
10fd = mopen(TMPDIR + filesep() + ['mclose_tst_1','mclose_tst_2'],'wt');
11mputl("test string 1",fd(1));
12mputl("test string 2",fd(2));
13mclose(fd);
14
15fd = mopen(TMPDIR + filesep() + ['mclose_tst_1','mclose_tst_2']);
16str = [mgetl(fd(1)),mgetl(fd(2))];
17mclose(fd);
18
19assert_checkequal(str,["test string 1","test string 2"]); \ No newline at end of file