add checkNamedArguments function to get unexpected named arguments. 71/19571/8
Antoine ELIAS [Sun, 3 Dec 2017 16:43:06 +0000 (17:43 +0100)]
Change-Id: Ie74d090a264559f9248eeacbdda64628e0c787bb

19 files changed:
scilab/modules/ast/includes/symbol/context.hxx
scilab/modules/ast/includes/symbol/variables.hxx
scilab/modules/ast/includes/system_env/configvariable.hxx
scilab/modules/ast/src/cpp/ast/debuggervisitor.cpp
scilab/modules/ast/src/cpp/symbol/context.cpp
scilab/modules/ast/src/cpp/symbol/variables.cpp
scilab/modules/ast/src/cpp/system_env/configvariable.cpp
scilab/modules/ast/src/cpp/types/function.cpp
scilab/modules/core/Makefile.am
scilab/modules/core/Makefile.in
scilab/modules/core/help/en_US/variables/checkNamedArguments.xml [new file with mode: 0644]
scilab/modules/core/includes/core_gw.hxx
scilab/modules/core/sci_gateway/cpp/core_gw.cpp
scilab/modules/core/sci_gateway/cpp/core_gw.vcxproj
scilab/modules/core/sci_gateway/cpp/core_gw.vcxproj.filters
scilab/modules/core/sci_gateway/cpp/sci_checkNamedArguments.cpp [new file with mode: 0644]
scilab/modules/core/sci_gateway/cpp/sci_debug.cpp
scilab/modules/core/sci_gateway/cpp/sci_where.cpp
scilab/modules/core/tests/unit_tests/checkNamedArguments.tst [new file with mode: 0644]

index cf5dff1..6b9df0e 100644 (file)
@@ -87,6 +87,7 @@ public:
     int getFunctionsName(std::list<std::wstring>& lst);
     int getVarsNameForWho(std::list<std::wstring>& lst, bool sorted);
     int getGlobalNameForWho(std::list<std::wstring>& lst, bool sorted);
+    int getCurrentScope(std::list<std::wstring>& lst, bool sorted);
     int getWhereIs(std::list<std::wstring>& lst, const std::wstring& _str);
     int getLibrariesList(std::list<std::wstring>& lst);
     int getVarsToVariableBrowser(std::list<Variable*>& lst);
index f91e565..c96549d 100644 (file)
@@ -162,6 +162,7 @@ struct Variables
     int getFunctionList(std::list<Symbol>& lst, std::wstring _stModuleName, int _iLevel);
     int getFunctionList(std::list<types::Callable *>& lst, std::wstring _stModuleName, int _iLevel);
     int getVarsToVariableBrowser(std::list<Variable*>& lst);
+    int getCurrentScope(std::list<std::wstring>& lst, int level, bool sorted);
     bool putInPreviousScope(Variable* _var, types::InternalType* _pIT, int _iLevel);
 
     //globals
index 76a1c68..d358225 100644 (file)
@@ -417,12 +417,12 @@ public :
     {
         int m_line;
         int m_absolute_line;
-        int m_macro_first_line;
-        std::wstring m_name;
+        types::Callable* call;
         std::wstring m_file_name;
-        WhereEntry(int line, int absolute_line, const std::wstring& name, int first_line, const std::wstring& file_name) :
-            m_line(line), m_absolute_line(absolute_line), m_macro_first_line(first_line), m_name(name), m_file_name(file_name) {}
+        WhereEntry(int line, int absolute_line, types::Callable* pCall, const std::wstring& file_name) :
+            m_line(line), m_absolute_line(absolute_line), call(pCall), m_file_name(file_name) {}
     };
+
     typedef std::vector<WhereEntry> WhereVector;
 
     static void where_begin(int _iLineNum, int _iLineLocation, types::Callable* _pCall);
index d38497c..2f40e73 100644 (file)
@@ -89,7 +89,7 @@ void DebuggerVisitor::visit(const SeqExp  &e)
                 if (lWhereAmI.size() != 0 && manager->getBreakPointCount() != 0)
                 {
                     debugger::Breakpoints bps = manager->getAllBreakPoint();
-                    std::wstring functionName = lWhereAmI.back().m_name;
+                    std::wstring functionName = lWhereAmI.back().call->getName();
                     int i = -1;
                     for (const auto & bp : bps)
                     {
@@ -288,7 +288,7 @@ void DebuggerVisitor::visit(const SeqExp  &e)
                 if (filename.empty())
                 {
                     //error in a console script
-                    std::wstring functionName = lWhereAmI.back().m_name;
+                    std::wstring functionName = lWhereAmI.back().call->getName();
                     manager->errorInScript(functionName, exp);
                 }
                 else
index ce6914a..30b3766 100644 (file)
@@ -631,6 +631,11 @@ int Context::getVarsToVariableBrowser(std::list<Variable*>& lst)
     return static_cast<int>(lst.size());
 }
 
+int Context::getCurrentScope(std::list<std::wstring>& lst, bool sorted)
+{
+    return variables.getCurrentScope(lst, m_iLevel, sorted);
+}
+
 void Context::updateProtection(bool protect)
 {
     if (varStack.empty() == false)
index d83addd..a87fea2 100644 (file)
@@ -443,6 +443,28 @@ int Variables::getVarsToVariableBrowser(std::list<Variable*>& lst)
     return static_cast<int>(lst.size());
 }
 
+int Variables::getCurrentScope(std::list<std::wstring>& lst, int level, bool sorted)
+{
+    for (auto var : vars)
+    {
+        if (var.second->empty() == false)
+        {
+            if (var.second->top()->m_iLevel == level)
+            {
+                types::InternalType* pIT = var.second->top()->m_pIT;
+                lst.push_back(var.first.getName());
+            }
+        }
+    }
+
+    if (sorted)
+    {
+        lst.sort();
+    }
+
+    return static_cast<int>(lst.size());
+}
+
 bool Variables::putInPreviousScope(Variable* _var, types::InternalType* _pIT, int _iLevel)
 {
     if (_var->empty())
index ff5ab2d..25b9723 100644 (file)
@@ -1185,7 +1185,7 @@ void ConfigVariable::where_begin(int _iLineNum, int _iLineLocation, types::Calla
         wstrFileName = pM->getFileName();
     }
 
-    m_Where.emplace_back(_iLineNum, _iLineLocation, pCall->getName(), pCall->getFirstLine(), wstrFileName);
+    m_Where.emplace_back(_iLineNum, _iLineLocation, pCall, wstrFileName);
 }
 
 void ConfigVariable::where_end()
@@ -1231,18 +1231,18 @@ void ConfigVariable::whereErrorToString(std::wostringstream &ostr)
     // get max length of functions name and check if exec or execstr have been called.
     for (auto & where : m_WhereError)
     {
-        if (isExecstr == false && where.m_name == L"execstr")
+        if (isExecstr == false && where.call->getName() == L"execstr")
         {
             isExecstr = true;
             continue;
         }
-        else if (isExecfile == false && where.m_name == L"exec")
+        else if (isExecfile == false && where.call->getName() == L"exec")
         {
             isExecfile = true;
             continue;
         }
 
-        iLenName = std::max((int)where.m_name.length(), iLenName);
+        iLenName = std::max((int)where.call->getName().length(), iLenName);
 
         // in case of bin file, the file path and line is displayed only if the associated .sci file exists
         if (where.m_file_name != L"" && where.m_file_name.find(L".bin") != std::wstring::npos)
@@ -1290,7 +1290,7 @@ void ConfigVariable::whereErrorToString(std::wostringstream &ostr)
         }
         else
         {
-            if (where.m_name == L"execstr")
+            if (where.call->getName() == L"execstr")
             {
                 isExecstr = true;
                 wchar_t wcsTmp[bsiz];
@@ -1298,7 +1298,7 @@ void ConfigVariable::whereErrorToString(std::wostringstream &ostr)
                 ostr << wcsTmp << std::endl;
                 continue;
             }
-            else if (where.m_name == L"exec")
+            else if (where.call->getName() == L"exec")
             {
                 wchar_t wcsTmp[bsiz];
                 os_swprintf(wcsTmp, bsiz, wstrExecFile.c_str(), where.m_line);
@@ -1314,12 +1314,12 @@ void ConfigVariable::whereErrorToString(std::wostringstream &ostr)
         }
 
         ostr.width(iLenName);
-        ostr << where.m_name;
+        ostr << where.call->getName();
 
         if (where.m_file_name != L"")
         {
             // -1 because the first line of a function dec is : "function myfunc()"
-            ostr << L"( " << where.m_file_name << L" " << _W("line") << L" " << where.m_macro_first_line + where.m_line - 1 << L" )";
+            ostr << L"( " << where.m_file_name << L" " << _W("line") << L" " << where.call->getFirstLine() + where.m_line - 1 << L" )";
         }
 
         ostr << std::endl;
@@ -1342,7 +1342,7 @@ void ConfigVariable::fillWhereError(int _iErrorLine)
         m_WhereError.reserve(m_Where.size());
         for (auto where = m_Where.rbegin(); where != m_Where.rend(); ++where)
         {
-            m_WhereError.emplace_back(iTmp, (*where).m_absolute_line, (*where).m_name, (*where).m_macro_first_line, (*where).m_file_name);
+            m_WhereError.emplace_back(iTmp, (*where).m_absolute_line, (*where).call, (*where).m_file_name);
             iTmp = (*where).m_line;
         }
     }
index 2fc687a..c5da1eb 100644 (file)
@@ -41,7 +41,7 @@ extern "C"
 // dummy function definition for non nwni compatible modules
 static void dummy()
 {
-    char* fname = wide_string_to_UTF8(ConfigVariable::getWhere().back().m_name.c_str());
+    char* fname = wide_string_to_UTF8(ConfigVariable::getWhere().back().call->getName().c_str());
     Scierror(999, _("Scilab '%s' function disabled in -nogui or -nwni mode.\n"), fname);
     FREE(fname);
 }
index 6838250..a223907 100644 (file)
@@ -124,7 +124,8 @@ GATEWAY_CPP_SOURCES = \
        sci_gateway/cpp/sci_mlist.cpp \
        sci_gateway/cpp/sci_isfield.cpp \
        sci_gateway/cpp/sci_oldEmptyBehaviour.cpp \
-       sci_gateway/cpp/sci_fieldnames.cpp
+       sci_gateway/cpp/sci_fieldnames.cpp \
+       sci_gateway/cpp/sci_checkNamedArguments.cpp
 
 if ENABLE_DEBUG
 GATEWAY_CPP_SOURCES += \
index 0d8c73b..1a7ccfe 100644 (file)
@@ -252,7 +252,7 @@ libscicore_algo_la_OBJECTS = $(am_libscicore_algo_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
 am__v_lt_0 = --silent
-am__v_lt_1 = 
+am__v_lt_1 =
 @MAINTAINER_MODE_FALSE@am_libscicore_algo_la_rpath =
 @MAINTAINER_MODE_TRUE@am_libscicore_algo_la_rpath =
 am__DEPENDENCIES_1 =
@@ -293,6 +293,7 @@ am__libscicore_la_SOURCES_DIST = sci_gateway/c/sci_getdebuginfo.c \
        sci_gateway/cpp/sci_mlist.cpp sci_gateway/cpp/sci_isfield.cpp \
        sci_gateway/cpp/sci_oldEmptyBehaviour.cpp \
        sci_gateway/cpp/sci_fieldnames.cpp \
+       sci_gateway/cpp/sci_checkNamedArguments.cpp \
        sci_gateway/cpp/sci_inspectorDeleteUnreferencedItems.cpp \
        sci_gateway/cpp/sci_inspectorGetItem.cpp \
        sci_gateway/cpp/sci_inspectorGetItemCount.cpp \
@@ -362,6 +363,7 @@ am__objects_6 = sci_gateway/cpp/libscicore_la-core_gw.lo \
        sci_gateway/cpp/libscicore_la-sci_isfield.lo \
        sci_gateway/cpp/libscicore_la-sci_oldEmptyBehaviour.lo \
        sci_gateway/cpp/libscicore_la-sci_fieldnames.lo \
+       sci_gateway/cpp/libscicore_la-sci_checkNamedArguments.lo \
        $(am__objects_5)
 am_libscicore_la_OBJECTS = $(am__objects_4) $(am__objects_6)
 libscicore_la_OBJECTS = $(am_libscicore_la_OBJECTS)
@@ -378,11 +380,11 @@ am__v_P_1 = :
 AM_V_GEN = $(am__v_GEN_@AM_V@)
 am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
 am__v_GEN_0 = @echo "  GEN     " $@;
-am__v_GEN_1 = 
+am__v_GEN_1 =
 AM_V_at = $(am__v_at_@AM_V@)
 am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
 am__v_at_0 = @
-am__v_at_1 = 
+am__v_at_1 =
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/modules/core/includes
 depcomp = $(SHELL) $(top_srcdir)/config/depcomp
 am__depfiles_maybe = depfiles
@@ -396,7 +398,7 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 AM_V_CC = $(am__v_CC_@AM_V@)
 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
 am__v_CC_0 = @echo "  CC      " $@;
-am__v_CC_1 = 
+am__v_CC_1 =
 CCLD = $(CC)
 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -404,7 +406,7 @@ LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
 AM_V_CCLD = $(am__v_CCLD_@AM_V@)
 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
 am__v_CCLD_0 = @echo "  CCLD    " $@;
-am__v_CCLD_1 = 
+am__v_CCLD_1 =
 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
 LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
@@ -414,7 +416,7 @@ LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
 AM_V_CXX = $(am__v_CXX_@AM_V@)
 am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
 am__v_CXX_0 = @echo "  CXX     " $@;
-am__v_CXX_1 = 
+am__v_CXX_1 =
 CXXLD = $(CXX)
 CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
@@ -422,14 +424,14 @@ CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
 AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
 am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
 am__v_CXXLD_0 = @echo "  CXXLD   " $@;
-am__v_CXXLD_1 = 
+am__v_CXXLD_1 =
 F77COMPILE = $(F77) $(AM_FFLAGS) $(FFLAGS)
 LTF77COMPILE = $(LIBTOOL) $(AM_V_lt) --tag=F77 $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=compile $(F77) $(AM_FFLAGS) $(FFLAGS)
 AM_V_F77 = $(am__v_F77_@AM_V@)
 am__v_F77_ = $(am__v_F77_@AM_DEFAULT_V@)
 am__v_F77_0 = @echo "  F77     " $@;
-am__v_F77_1 = 
+am__v_F77_1 =
 F77LD = $(F77)
 F77LINK = $(LIBTOOL) $(AM_V_lt) --tag=F77 $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(F77LD) $(AM_FFLAGS) $(FFLAGS) \
@@ -437,7 +439,7 @@ F77LINK = $(LIBTOOL) $(AM_V_lt) --tag=F77 $(AM_LIBTOOLFLAGS) \
 AM_V_F77LD = $(am__v_F77LD_@AM_V@)
 am__v_F77LD_ = $(am__v_F77LD_@AM_DEFAULT_V@)
 am__v_F77LD_0 = @echo "  F77LD   " $@;
-am__v_F77LD_1 = 
+am__v_F77LD_1 =
 SOURCES = $(libscicore_algo_la_SOURCES) $(libscicore_la_SOURCES)
 DIST_SOURCES = $(libscicore_algo_la_SOURCES) \
        $(am__libscicore_la_SOURCES_DIST)
@@ -858,7 +860,8 @@ GATEWAY_CPP_SOURCES = sci_gateway/cpp/core_gw.cpp \
        sci_gateway/cpp/sci_typeof.cpp sci_gateway/cpp/sci_tlist.cpp \
        sci_gateway/cpp/sci_mlist.cpp sci_gateway/cpp/sci_isfield.cpp \
        sci_gateway/cpp/sci_oldEmptyBehaviour.cpp \
-       sci_gateway/cpp/sci_fieldnames.cpp $(am__append_1)
+       sci_gateway/cpp/sci_fieldnames.cpp \
+       sci_gateway/cpp/sci_checkNamedArguments.cpp $(am__append_1)
 libscicore_la_CPPFLAGS = -I$(srcdir)/includes/ -I$(srcdir)/src/c/ \
        -I$(srcdir)/src/cpp/ -I$(top_srcdir)/modules/ast/includes/ast/ \
        -I$(top_srcdir)/modules/ast/includes/exps/ \
@@ -983,7 +986,7 @@ TARGETS_ALL = $(am__append_3)
 ################ MACROS ######################
 # Rule to build a macro
 # NOT USED  AT THE MOMENT
-SUFFIXES = .sci 
+SUFFIXES = .sci
 
 ########### INSTALL DOCUMENTATION ###################
 
@@ -1025,7 +1028,7 @@ EXAMPLES_DIR = examples
 JARDIR = jar/
 # JAR files mask
 JARMASK = *.jar
-# Chapter file 
+# Chapter file
 HELP_CHAPTERDIR = help/
 HELP_CHAPTERFILE = addchapter.sce
 HELP_CHAPTERLANG = en_US fr_FR pt_BR
@@ -1236,7 +1239,7 @@ src/fortran/write_inter.lo: src/fortran/$(am__dirstamp) \
 src/fortran/read_inter.lo: src/fortran/$(am__dirstamp) \
        src/fortran/$(DEPDIR)/$(am__dirstamp)
 
-libscicore-algo.la: $(libscicore_algo_la_OBJECTS) $(libscicore_algo_la_DEPENDENCIES) $(EXTRA_libscicore_algo_la_DEPENDENCIES) 
+libscicore-algo.la: $(libscicore_algo_la_OBJECTS) $(libscicore_algo_la_DEPENDENCIES) $(EXTRA_libscicore_algo_la_DEPENDENCIES)
        $(AM_V_CXXLD)$(CXXLINK) $(am_libscicore_algo_la_rpath) $(libscicore_algo_la_OBJECTS) $(libscicore_algo_la_LIBADD) $(LIBS)
 sci_gateway/c/$(am__dirstamp):
        @$(MKDIR_P) sci_gateway/c
@@ -1415,6 +1418,9 @@ sci_gateway/cpp/libscicore_la-sci_oldEmptyBehaviour.lo:  \
 sci_gateway/cpp/libscicore_la-sci_fieldnames.lo:  \
        sci_gateway/cpp/$(am__dirstamp) \
        sci_gateway/cpp/$(DEPDIR)/$(am__dirstamp)
+sci_gateway/cpp/libscicore_la-sci_checkNamedArguments.lo:  \
+       sci_gateway/cpp/$(am__dirstamp) \
+       sci_gateway/cpp/$(DEPDIR)/$(am__dirstamp)
 sci_gateway/cpp/libscicore_la-sci_inspectorDeleteUnreferencedItems.lo:  \
        sci_gateway/cpp/$(am__dirstamp) \
        sci_gateway/cpp/$(DEPDIR)/$(am__dirstamp)
@@ -1437,7 +1443,7 @@ sci_gateway/cpp/libscicore_la-sci_inspectorGetFunctionList.lo:  \
        sci_gateway/cpp/$(am__dirstamp) \
        sci_gateway/cpp/$(DEPDIR)/$(am__dirstamp)
 
-libscicore.la: $(libscicore_la_OBJECTS) $(libscicore_la_DEPENDENCIES) $(EXTRA_libscicore_la_DEPENDENCIES) 
+libscicore.la: $(libscicore_la_OBJECTS) $(libscicore_la_DEPENDENCIES) $(EXTRA_libscicore_la_DEPENDENCIES)
        $(AM_V_CXXLD)$(libscicore_la_LINK) $(am_libscicore_la_rpath) $(libscicore_la_OBJECTS) $(libscicore_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
@@ -1465,6 +1471,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_argn.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_banner.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_cell.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_checkNamedArguments.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_clear.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_clearfun.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_clearglobal.Plo@am__quote@
@@ -2282,6 +2289,13 @@ sci_gateway/cpp/libscicore_la-sci_fieldnames.lo: sci_gateway/cpp/sci_fieldnames.
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicore_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sci_gateway/cpp/libscicore_la-sci_fieldnames.lo `test -f 'sci_gateway/cpp/sci_fieldnames.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_fieldnames.cpp
 
+sci_gateway/cpp/libscicore_la-sci_checkNamedArguments.lo: sci_gateway/cpp/sci_checkNamedArguments.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicore_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sci_gateway/cpp/libscicore_la-sci_checkNamedArguments.lo -MD -MP -MF sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_checkNamedArguments.Tpo -c -o sci_gateway/cpp/libscicore_la-sci_checkNamedArguments.lo `test -f 'sci_gateway/cpp/sci_checkNamedArguments.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_checkNamedArguments.cpp
+@am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_checkNamedArguments.Tpo sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_checkNamedArguments.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     $(AM_V_CXX)source='sci_gateway/cpp/sci_checkNamedArguments.cpp' object='sci_gateway/cpp/libscicore_la-sci_checkNamedArguments.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicore_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o sci_gateway/cpp/libscicore_la-sci_checkNamedArguments.lo `test -f 'sci_gateway/cpp/sci_checkNamedArguments.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_checkNamedArguments.cpp
+
 sci_gateway/cpp/libscicore_la-sci_inspectorDeleteUnreferencedItems.lo: sci_gateway/cpp/sci_inspectorDeleteUnreferencedItems.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libscicore_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT sci_gateway/cpp/libscicore_la-sci_inspectorDeleteUnreferencedItems.lo -MD -MP -MF sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_inspectorDeleteUnreferencedItems.Tpo -c -o sci_gateway/cpp/libscicore_la-sci_inspectorDeleteUnreferencedItems.lo `test -f 'sci_gateway/cpp/sci_inspectorDeleteUnreferencedItems.cpp' || echo '$(srcdir)/'`sci_gateway/cpp/sci_inspectorDeleteUnreferencedItems.cpp
 @am__fastdepCXX_TRUE@  $(AM_V_at)$(am__mv) sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_inspectorDeleteUnreferencedItems.Tpo sci_gateway/cpp/$(DEPDIR)/libscicore_la-sci_inspectorDeleteUnreferencedItems.Plo
@@ -2726,7 +2740,7 @@ check-code:
 @NEED_JAVA_TRUE@               $(ANT) clean; \
 @NEED_JAVA_TRUE@       fi;
 
-# If the user request for the SWIG generation of the wrappers Java => C/C++ 
+# If the user request for the SWIG generation of the wrappers Java => C/C++
 # We call the target swig-build on the variable SWIG_WRAPPERS
 
 @SWIG_TRUE@swig: $(SWIG_WRAPPERS)
@@ -2748,7 +2762,7 @@ check-code:
 @SWIG_TRUE@            done; \
 @SWIG_TRUE@    fi
 
-# If the user request for the SWIG generation of the wrappers Java => C/C++ 
+# If the user request for the SWIG generation of the wrappers Java => C/C++
 # We call the target swig-build on the variable SWIG_WRAPPERS
 
 @GIWS_TRUE@giws: $(GIWS_WRAPPERS)
@@ -2769,7 +2783,7 @@ check-code:
 @GIWS_TRUE@giws-exception:
 @GIWS_TRUE@    @GIWS_OUTPUTDIR=src/jni/;\
 @GIWS_TRUE@    echo "GIWS: Generation of exception class ..."; \
-@GIWS_TRUE@    $(GIWS_BIN) --generate-exception-class --output-dir $$GIWS_OUTPUTDIR 
+@GIWS_TRUE@    $(GIWS_BIN) --generate-exception-class --output-dir $$GIWS_OUTPUTDIR
 
 macros:
        -@( if test ! -x $(top_builddir)/scilab-bin; then \
diff --git a/scilab/modules/core/help/en_US/variables/checkNamedArguments.xml b/scilab/modules/core/help/en_US/variables/checkNamedArguments.xml
new file mode 100644 (file)
index 0000000..ce87a1d
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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="checkNamedArguments">
+    <refnamediv>
+        <refname>checkNamedArguments</refname>
+        <refpurpose>Return list of unexpected named arguments</refpurpose>
+    </refnamediv>
+    <refsynopsisdiv>
+        <title>Syntax</title>
+        <synopsis>names = checkNamedArguments()</synopsis>
+    </refsynopsisdiv>
+    <refsection>
+        <title>Arguments</title>
+        <variablelist>
+            <varlistentry>
+                <term>names</term>
+                <listitem>
+                    <para>a vector of string with names of variables</para>
+                </listitem>
+            </varlistentry>
+        </variablelist>
+    </refsection>
+    <refsection>
+        <title>Description</title>
+        <para>
+                       Returns names of named variables passed to current function but that are not in the function prototype.
+        </para>
+    </refsection>
+    <refsection>
+        <title>Examples</title>
+        <programlisting role="example"><![CDATA[
+function foo(a,b)
+    x = checkNamedArguments();
+       disp(x, "Named Variable:");
+endfunction
+
+//No additional named variable
+foo(1);
+foo(1, 2);
+foo(a = 1, b = 2);
+foo(b = 2, a = 2);
+
+//With additional named variables
+foo(a = 1, c = 2);
+foo(c = 2, b = 2); ]]>
+               </programlisting>
+    </refsection>
+    <refsection role="see also">
+        <title>See also</title>
+        <simplelist type="inline">
+            <member>
+                <link linkend="who">who</link>
+            </member>
+        </simplelist>
+    </refsection>
+</refentry>
index fa38969..9dfac6f 100644 (file)
@@ -87,6 +87,7 @@ CPP_GATEWAY_PROTOTYPE(sci_mlist_gw);
 CPP_GATEWAY_PROTOTYPE(sci_isfield);
 CPP_GATEWAY_PROTOTYPE(sci_fieldnames);
 CPP_GATEWAY_PROTOTYPE(sci_oldEmptyBehaviour);
+CPP_GATEWAY_PROTOTYPE(sci_checkNamedArguments);
 
 #ifndef NDEBUG
 CPP_GATEWAY_PROTOTYPE(sci_inspectorGetItemCount);
index e4865e2..7c2ae09 100644 (file)
@@ -79,6 +79,7 @@ int CoreModule::Load()
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"isfield", &sci_isfield, MODULE_NAME));
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"fieldnames", &sci_fieldnames, MODULE_NAME));
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"oldEmptyBehaviour", &sci_oldEmptyBehaviour, MODULE_NAME));
+    symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"checkNamedArguments", &sci_checkNamedArguments, MODULE_NAME));
 
 #ifndef NDEBUG
     symbol::Context::getInstance()->addFunction(types::Function::createFunction(L"inspectorGetItemCount", &sci_inspectorGetItemCount, MODULE_NAME));
index 2cb29ba..e5ef0ae 100644 (file)
   <ItemGroup>
     <ClCompile Include="sci_analyzeroptions.cpp" />
     <ClCompile Include="sci_cell.cpp" />
+    <ClCompile Include="sci_checkNamedArguments.cpp" />
     <ClCompile Include="sci_clearfun.cpp" />
     <ClCompile Include="sci_errclear.cpp" />
     <ClCompile Include="sci_fieldnames.cpp" />
index 6680f8c..b152ee0 100644 (file)
     <ClCompile Include="sci_oldEmptyBehaviour.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="sci_checkNamedArguments.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\includes\banner.hxx">
diff --git a/scilab/modules/core/sci_gateway/cpp/sci_checkNamedArguments.cpp b/scilab/modules/core/sci_gateway/cpp/sci_checkNamedArguments.cpp
new file mode 100644 (file)
index 0000000..6967a5d
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+*  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+*  Copyright (C) 2017 - ESI - Antoine ELIAS
+*
+* Copyright (C) 2012 - 2016 - Scilab Enterprises
+*
+* This file is hereby licensed under the terms of the GNU GPL v2.0,
+* pursuant to article 5.3.4 of the CeCILL v.2.1.
+* This file was originally licensed under the terms of the CeCILL v2.1,
+* and continues to be available under such terms.
+* For more information, see the COPYING file which you should have received
+* along with this program.
+*
+*/
+
+#include "core_gw.hxx"
+#include "function.hxx"
+#include "macro.hxx"
+#include "context.hxx"
+#include "double.hxx"
+#include "string.hxx"
+#include "configvariable.hxx"
+
+extern "C"
+{
+#include "localization.h"
+#include "Scierror.h"
+#include "sciprint.h"
+}
+
+const char fname[] = "checkNamedArguments";
+types::Function::ReturnValue sci_checkNamedArguments(types::typed_list &in, int _iRetCount, types::typed_list &out)
+{
+    int size = 0;
+    symbol::Context* ctx = symbol::Context::getInstance();
+    int rhs = static_cast<int>(in.size());             
+    std::vector<std::wstring> proto;
+
+    if (ctx->getScopeLevel() < 2)
+    {
+        Scierror(999, _("%s: must be call from a function.\n"), fname);
+        return types::Function::Error;
+    }
+
+    if (rhs != 0)
+    {
+        Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), fname, 0);
+        return types::Function::Error;
+    }
+
+    if (_iRetCount != 1)
+    {
+        Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), fname, 1);
+        return types::Function::Error;
+    }
+
+    //get before last where
+    const ConfigVariable::WhereEntry& where = *(++ConfigVariable::getWhere().crbegin());
+    if (where.call->isMacro())
+    {
+        types::Macro* m = (types::Macro*)where.call;
+        auto inputs = m->getInputs();
+        proto.reserve(inputs->size());
+        for (auto i : *inputs)
+        {
+            std::wstring var(i->getSymbol().getName());
+            if (var != L"varargin")
+            {
+                proto.push_back(var);
+            }
+        }
+
+        size = (int)proto.size();
+    }
+
+    std::list<std::wstring> lst;
+    int count = ctx->getCurrentScope(lst, true);
+
+       //remove nargin/nargout//varargin
+       lst.remove(L"nargin");
+       lst.remove(L"nargout");
+       lst.remove(L"varargin");
+
+       for (int i = 0; i < size; ++i)
+    {
+               lst.remove(proto[i]);
+    }
+
+       count = (int)lst.size();
+    if (count == 0)
+    {
+        out.push_back(types::Double::Empty());
+        return types::Function::OK;
+    }
+
+    types::String* pOut = new types::String(count, 1);
+    int i = 0;
+    for (auto v : lst)
+    {
+        pOut->set(i++, v.data());
+    }
+
+    out.push_back(pOut);
+    return types::Function::OK;
+}
index 37f0c72..5488014 100644 (file)
@@ -490,12 +490,12 @@ types::Function::ReturnValue sci_debug(types::typed_list &in, int _iRetCount, ty
             auto it1 = where.rbegin();
             auto it2 = ++where.rbegin();
 
-            sciprint(_(BT_PRINT), 1, it2->m_name.data(), curLine);
+            sciprint(_(BT_PRINT), 1, it2->call->getName().data(), curLine);
             ++it1;
             ++it2;
             for (int j = 2; it2 != where.rend(); it1++, it2++, j++)
             {
-                sciprint(_(BT_PRINT), j, it2->m_name.data(), it1->m_line);
+                sciprint(_(BT_PRINT), j, it2->call->getName().data(), it1->m_line);
             }
 
             return types::Function::OK;
index 7d4036f..4963b11 100644 (file)
@@ -58,10 +58,10 @@ types::Function::ReturnValue sci_where(types::typed_list &in, int _iRetCount, ty
     for (int i = 0; it != where.rend(); it++, i++)
     {
         pDblLines->set(i + 1, it->m_line);
-        pStrNames->set(i, it->m_name.c_str());
+        pStrNames->set(i, it->call->getName().c_str());
     }
 
-    pStrNames->set(static_cast<int>(where.size()) - 1, where.back().m_name.c_str());
+    pStrNames->set(static_cast<int>(where.size()) - 1, where.back().call->getName().c_str());
 
     out.push_back(pDblLines);
     out.push_back(pStrNames);
diff --git a/scilab/modules/core/tests/unit_tests/checkNamedArguments.tst b/scilab/modules/core/tests/unit_tests/checkNamedArguments.tst
new file mode 100644 (file)
index 0000000..3fb6c75
--- /dev/null
@@ -0,0 +1,50 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2017 - ESI - Antoine ELIAS
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+
+function foo_good(a,b)
+    x = checkNamedArguments();
+    assert_checktrue(isempty(x));
+endfunction
+
+foo_good(1);
+foo_good(1, 2);
+foo_good(a = 1, b = 2);
+foo_good(b = 2, a = 2);
+
+function foo_bad(a,b)
+    x = checkNamedArguments();
+    assert_checkfalse(isempty(x));
+endfunction
+
+foo_bad(a = 1, c = 2);
+foo_bad(c = 2, b = 2);
+
+
+function foo_varargin_good(a, b, varargin)
+    x = checkNamedArguments();
+   assert_checktrue(isempty(x));
+endfunction
+
+foo_varargin_good(1);
+foo_varargin_good(1, 2);
+foo_varargin_good(a = 1, b = 2);
+foo_varargin_good(b = 2, a = 2);
+foo_varargin_good(b = 2, a = 2, 3, 4);
+
+function foo_varargin_bad(a, b, varargin)
+    x = checkNamedArguments();
+    assert_checkfalse(isempty(x));
+endfunction
+
+foo_varargin_bad(c = 2);
+foo_varargin_bad(a = 1, c = 2);
+foo_varargin_bad(c = 1, b = 2);
+foo_varargin_bad(b = 2, c = 3, a = 3, 4);
+foo_varargin_bad(c = 3, a = 1, b = 2, 4);