Merge remote-tracking branch 'origin/master' into windows
[scilab.git] / scilab / modules / core / sci_gateway / cpp / sci_argn.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2010-2010 - DIGITEO - Antoine ELIAS
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 #include "core_gw.hxx"
17 #include "function.hxx"
18 #include "context.hxx"
19 #include "double.hxx"
20
21 extern "C"
22 {
23 #include "localization.h"
24 #include "Scierror.h"
25 }
26
27 types::Function::ReturnValue sci_argn(types::typed_list &in, int _iRetCount, types::typed_list &out)
28 {
29     int iRhs = static_cast<int>(in.size());
30     //check input arguments
31     if (iRhs > 1)
32     {
33         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected."), "argn", 0, 1);
34         return types::Function::Error;
35     }
36
37     //check output arguments
38     if (iRhs == 0 && _iRetCount > 2)
39     {
40         Scierror(41, _("%s: Wrong number of output arguments: %d expected.\n"), "argn", 2);
41         return types::Function::Error;
42     }
43
44     //check input arguments types
45     for (int i = 0 ; i < in.size() ; i++)
46     {
47         if (in[i]->isDouble() == false)
48         {
49             Scierror(999, _("%s: Wrong type for input argument #%d: A real expected.\n"), "argn", i + 1);
50             return types::Function::Error;
51         }
52         else
53         {
54             if (in[i]->getAs<types::Double>()->getSize() != 1)
55             {
56                 Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "argn", i + 1);
57                 return types::Function::Error;
58             }
59             else
60             {
61                 if (in[i]->getAs<types::Double>()->isComplex())
62                 {
63                     Scierror(999, _("%s: Wrong type for input argument #%d: A real expected.\n"), "argn", i + 1);
64                     return types::Function::Error;
65                 }
66             }
67         }
68     }
69
70     symbol::Context* pContext = symbol::Context::getInstance();
71
72     types::InternalType* pIn = pContext->get(symbol::Symbol("nargin"));
73     types::InternalType* pOut = pContext->get(symbol::Symbol("nargout"));
74
75     if (pIn == NULL || pOut == NULL)
76     {
77         out.push_back(types::Double::Empty());
78         if (_iRetCount == 2)
79         {
80             out.push_back(types::Double::Empty());
81         }
82     }
83     else
84     {
85         if (iRhs == 0 && _iRetCount == 1)
86         {
87             //arng() returns lhs
88             out.push_back(pOut);
89         }
90         else if (iRhs == 0 && _iRetCount == 2)
91         {
92             //[a,b] = arng() returns lhs and rhs
93             out.push_back(pOut);
94             out.push_back(pIn);
95         }
96         else if (iRhs == 1)
97         {
98             //argn(x)
99             double dblVal = in[0]->getAs<types::Double>()->getReal(0, 0);
100             if (dblVal == 1)
101             {
102                 //x == 1 returns lhs
103                 out.push_back(pOut);
104             }
105             else if (dblVal == 2)
106             {
107                 //x == 2returns rhs
108                 out.push_back(pIn);
109             }
110             else if (dblVal == 0)
111             {
112                 //x == 0 returns lhs
113                 out.push_back(pOut);
114                 if (_iRetCount == 2)
115                 {
116                     //[a,b] = argn(0) returns lhs ans rhs
117                     out.push_back(pIn);
118                 }
119             }
120             else
121             {
122                 Scierror(999, _("%s: Wrong value for input argument #%d: '%s', '%s' or '%s'.\n"), "argn", 1, "0", "1", "2");
123                 return types::Function::Error;
124             }
125         }
126     }
127
128     return types::Function::OK;
129 }