* Bug 16365 fixed: median(m,'r'|'c') was wrong after 5dc990
[scilab.git] / scilab / modules / string / sci_gateway / cpp / sci_length.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) INRIA 2007 - Cong WU
4  * Copyright (C) INRIA 2008 - Allan CORNET
5  * Copyright (C) DIGITEO 2009 - Allan CORNET
6  *
7  * Copyright (C) 2012 - 2016 - Scilab Enterprises
8  *
9  * This file is hereby licensed under the terms of the GNU GPL v2.0,
10  * pursuant to article 5.3.4 of the CeCILL v.2.1.
11  * This file was originally licensed under the terms of the CeCILL v2.1,
12  * and continues to be available under such terms.
13  * For more information, see the COPYING file which you should have received
14  * along with this program.
15  *
16  */
17
18 /* desc : For usual or polynomial matrix  n  is the int equal to
19    number of rows times number of columns of  M . (Also valid for  M
20    a boolean matrix)
21
22    For matrices made of character strings (and in particular for a
23    character string)  length  returns in  n  the length of entries of
24    the matrix of character strings  M .
25
26    The length of a list is the number of elements in the list
27    (also given by  size ).
28
29    length('123')  is  3 .  length([1,2;3,4])  is  4 .                     */
30 /*------------------------------------------------------------------------*/
31
32 #include "function.hxx"
33 #include "string.hxx"
34 #include "mlist.hxx"
35 #include "double.hxx"
36 #include "funcmanager.hxx"
37 #include "string_gw.hxx"
38 #include "context.hxx"
39 #include "overload.hxx"
40
41 extern "C"
42 {
43 #include "core_math.h"
44 #include "localization.h"
45 #include "Scierror.h"
46 }
47
48 /*----------------------------------------------------------------------------*/
49 /* get length */
50 static types::Double* lengthStrings(types::String* _pS);
51 static types::Double* lengthMatrix(types::GenericType* _pG);
52 static types::Double* lengthList(types::List* _pL);
53 /* !!! WARNING !!! : Read comments about length on sparse matrix */
54 //static Double lengthSparse(Sparse* _pS);
55 /*----------------------------------------------------------------------------*/
56 types::Function::ReturnValue sci_length(types::typed_list &in, int _iRetCount, types::typed_list &out)
57 {
58     types::Double* pOut = NULL;
59
60     if (in.size() != 1)
61     {
62         Scierror(999, _("%s: Wrong number of input argument(s): %d expected.\n"), "length", 1);
63         return types::Function::Error;
64     }
65
66     if (in[0]->isString())
67     {
68         pOut = lengthStrings(in[0]->getAs<types::String>());
69     }
70     else if (in[0]->isMList())
71     {
72         //build overload name and check if function exists.
73         types::MList* pML = in[0]->getAs<types::MList>();
74         std::wstring wst = L"%" + pML->getShortTypeStr() + L"_length";
75         symbol::Context* pCtx = symbol::Context::getInstance();
76         types::InternalType* pFunc = pCtx->get(symbol::Symbol(wst));
77         if (pFunc && pFunc->isCallable())
78         {
79             //call overload
80             Overload::generateNameAndCall(L"length", in, _iRetCount, out);
81             return types::Function::OK;
82         }
83
84         //MList without overloading, manage like a list
85         pOut = lengthList(in[0]->getAs<types::List>());
86     }
87     else if (in[0]->isList())
88     {
89         pOut = lengthList(in[0]->getAs<types::List>());
90     }
91     else if (in[0]->isGenericType())
92     {
93         pOut = lengthMatrix(in[0]->getAs<types::GenericType>());
94     }
95     else
96     {
97         Scierror(999, _("%s: Wrong type for input argument(s).\n"), "length");
98         return types::Function::Error;
99     }
100
101     out.push_back(pOut);
102     return types::Function::OK;
103 }
104 /*--------------------------------------------------------------------------*/
105 static types::Double* lengthStrings(types::String* _pS)
106 {
107     if (_pS == NULL)
108     {
109         return types::Double::Empty();
110     }
111
112     types::Double* pD = new types::Double(_pS->getDims(), _pS->getDimsArray());
113     wchar_t** pwst  = _pS->get();
114     double* pdbl    = pD->get();
115
116     for (int i = 0 ; i < _pS->getSize() ; i++)
117     {
118         pdbl[i] = static_cast<double>(wcslen(pwst[i]));
119     }
120     return pD;
121 }
122 /*--------------------------------------------------------------------------*/
123 static types::Double* lengthMatrix(types::GenericType* _pG)
124 {
125     if (_pG == NULL)
126     {
127         return types::Double::Empty();
128     }
129
130     return new types::Double(static_cast<double>(_pG->getSize()));
131 }
132 /*--------------------------------------------------------------------------*/
133 static types::Double* lengthList(types::List* _pL)
134 {
135     if (_pL == NULL)
136     {
137         return types::Double::Empty();
138     }
139
140     return new types::Double(static_cast<double>(_pL->getSize()));
141 }
142 /*--------------------------------------------------------------------------*/
143 //static Double lengthSparse(Sparse* _pS)
144 //{
145 //}
146 /*--------------------------------------------------------------------------*/