* Bug 16365 fixed: median(m,'r'|'c') was wrong after 5dc990
[scilab.git] / scilab / modules / string / sci_gateway / cpp / sci_strncpy.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) Digiteo 2011 - Cedric DELAMARRE
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
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.
9  * This file was originally licensed under the terms of the CeCILL v2.1,
10  * and continues to be available under such terms.
11  * For more information, see the COPYING file which you should have received
12  * along with this program.
13  *
14  */
15
16
17 #include "function.hxx"
18 #include "string.hxx"
19 #include "list.hxx"
20 #include "double.hxx"
21 #include "funcmanager.hxx"
22 #include "string_gw.hxx"
23
24 extern "C"
25 {
26 #include "sci_malloc.h"
27 #include "core_math.h"
28 #include "localization.h"
29 #include "Scierror.h"
30 }
31
32
33 types::Function::ReturnValue sci_strncpy(types::typed_list &in, int _iRetCount, types::typed_list &out)
34 {
35     types::String* pString      = NULL;
36     types::Double* pDouble      = NULL;
37     types::String* pOutString   = NULL;
38
39     if (in.size() != 2)
40     {
41         Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "strncpy", 2);
42         return types::Function::Error;
43     }
44     if (_iRetCount > 1)
45     {
46         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "strncpy", 1);
47         return types::Function::Error;
48     }
49     if (in[0]->isString() == false)
50     {
51         Scierror(999, _("%s: Wrong type for input argument #%d: Matrix of strings expected.\n"), "strncpy", 1);
52         return types::Function::Error;
53     }
54
55     if (in[1]->isDouble() == false)
56     {
57         Scierror(999, _("%s: Wrong type for input argument #%d: Matrix of integers expected.\n"), "strncpy", 2);
58         return types::Function::Error;
59     }
60
61     pString = in[0]->getAs<types::String>();
62     pDouble = in[1]->getAs<types::Double>();
63
64     if (pDouble->getSize() == 0)
65     {
66         Scierror(999, _("%s: Wrong size for input argument #%d: Non-empty matrix expected.\n"), "strncpy", 2);
67         return types::Function::Error;
68     }
69
70     //same dimension or 2nd arg scalar
71     if (pString->getSize() != pDouble->getSize() && pDouble->isScalar() == false)
72     {
73         Scierror(999, _("%s: Wrong size for input argument #%d.\n"), "strncpy", 2);
74         return types::Function::Error;
75     }
76
77     pOutString  = new types::String(pString->getDims(), pString->getDimsArray());
78
79     int j = 0; /* Input parameter two is dimension one */
80     for (int i = 0 ; i < pString->getSize() ; i++)
81     {
82         wchar_t *wcOutput   = NULL;
83         int sizeOfCopy      = 0;
84
85         if (pDouble->isScalar() == false)
86         {
87             j = i; /* Input parameter One & two have same dimension */
88         }
89
90         if (pDouble->get(j) < wcslen(pString->get(i)))
91         {
92             int iLen = (int)pDouble->get(j);
93             if (iLen < 0)
94             {
95                 iLen = 0;
96             }
97
98             wcOutput = (wchar_t*)MALLOC(sizeof(wchar_t) * (iLen + 1));
99             sizeOfCopy = iLen;
100         }
101         else
102         {
103             int iLen = (int)wcslen(pString->get(i));
104             wcOutput = (wchar_t*)MALLOC(sizeof(wchar_t) * (iLen + 1));
105             sizeOfCopy = iLen;
106         }
107
108         if (wcOutput)
109         {
110             wcsncpy(wcOutput, pString->get(i), sizeOfCopy);
111             wcOutput[sizeOfCopy] = L'\0';
112
113             pOutString->set(i, wcOutput);
114             FREE(wcOutput);
115             wcOutput = NULL;
116         }
117         else
118         {
119             delete pOutString;
120             Scierror(999, _("%s: No more memory.\n"), "strncpy");
121             return types::Function::Error;
122         }
123     }
124
125     out.push_back(pOutString);
126     return types::Function::OK;
127 }
128