exec : management of macro and macrofile.
[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  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include "core_gw.hxx"
14 #include "function.hxx"
15 #include "context.hxx"
16 #include "double.hxx"
17
18 extern "C"
19 {
20 #include "localization.h"
21 #include "Scierror.h"
22 }
23
24 using namespace types;
25
26 types::Function::ReturnValue sci_argn(types::typed_list &in, int _iRetCount, types::typed_list &out)
27 {
28     static symbol::Variable* varIn = NULL;
29     static symbol::Variable* varOut = NULL;
30
31     int iRhs = static_cast<int>(in.size());
32     //check input arguments
33     if (iRhs > 1)
34     {
35         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected."), "argn", 0, 1);
36         return Function::Error;
37     }
38
39     //check output arguments
40     if (iRhs == 0 && _iRetCount > 2)
41     {
42         Scierror(41, _("%s: Wrong number of output arguments: %d expected.\n"), "argn", 2);
43         return Function::Error;
44     }
45
46     //check input arguments types
47     for (int i = 0 ; i < in.size() ; i++)
48     {
49         if (in[i]->isDouble() == false)
50         {
51             Scierror(999, _("%s: Wrong type for input argument #%d: A real expected.\n"), "argn", i + 1);
52             return Function::Error;
53         }
54         else
55         {
56             if (in[i]->getAs<Double>()->getSize() != 1)
57             {
58                 Scierror(999, _("%s: Wrong type for input argument #%d: A scalar expected.\n"), "argn", i + 1);
59                 return Function::Error;
60             }
61             else
62             {
63                 if (in[i]->getAs<Double>()->isComplex())
64                 {
65                     Scierror(999, _("%s: Wrong type for input argument #%d: A real expected.\n"), "argn", i + 1);
66                     return Function::Error;
67                 }
68             }
69         }
70     }
71
72     symbol::Context* pContext = symbol::Context::getInstance();
73
74     InternalType *pIn = NULL;
75     InternalType *pOut = NULL;
76
77     if (varIn == NULL)
78     {
79         varIn = symbol::Context::getInstance()->getOrCreate(symbol::Symbol(L"nargin"));
80     }
81
82     if (varOut == NULL)
83     {
84         varOut = symbol::Context::getInstance()->getOrCreate(symbol::Symbol(L"nargout"));
85     }
86
87     pIn = pContext->get(varIn);
88     pOut = pContext->get(varOut);
89
90     if (pIn == NULL || pOut == NULL)
91     {
92         Double* pD = new Double(0);
93         out.push_back(pD);
94         if (_iRetCount == 2)
95         {
96             out.push_back(pD);
97         }
98     }
99     else
100     {
101         if (iRhs == 0 && _iRetCount == 1)
102         {
103             //arng() returns lhs
104             out.push_back(pOut);
105         }
106         else if (iRhs == 0 && _iRetCount == 2)
107         {
108             //[a,b] = arng() returns lhs and rhs
109             out.push_back(pOut);
110             out.push_back(pIn);
111         }
112         else if (iRhs == 1)
113         {
114             //argn(x)
115             double dblVal = in[0]->getAs<Double>()->getReal(0, 0);
116             if (dblVal == 1)
117             {
118                 //x == 1 returns lhs
119                 out.push_back(pOut);
120             }
121             else if (dblVal == 2)
122             {
123                 //x == 2returns rhs
124                 out.push_back(pIn);
125             }
126             else if (dblVal == 0)
127             {
128                 //x == 0 returns lhs
129                 out.push_back(pOut);
130                 if (_iRetCount == 2)
131                 {
132                     //[a,b] = argn(0) returns lhs ans rhs
133                     out.push_back(pIn);
134                 }
135             }
136             else
137             {
138                 Scierror(999, _("%s: Wrong value for input argument #%d: '%s', '%s' or '%s'.\n"), "argn", 1, "0", "1", "2");
139                 return Function::Error;
140             }
141         }
142     }
143
144     return types::Function::OK;
145 }