'hidden' macros from lib are visible only in main macro 85/15885/7
Antoine ELIAS [Thu, 29 Jan 2015 16:20:37 +0000 (17:20 +0100)]
Change-Id: Ifd233d237dc99606bbc8532d7876d01e22ff4d04

scilab/modules/ast/includes/types/macro.hxx
scilab/modules/ast/src/cpp/types/macro.cpp
scilab/modules/ast/src/cpp/types/macrofile.cpp
scilab/modules/ast/tests/unit_tests/library.dia.ref
scilab/modules/ast/tests/unit_tests/library.tst
scilab/modules/ast/tests/unit_tests/test_macro.sci [new file with mode: 0644]
scilab/modules/io/sci_gateway/cpp/sci_genlib.cpp

index 52c091c..92b8744 100644 (file)
@@ -82,6 +82,8 @@ public :
 
     bool operator==(const InternalType& it);
 
+    void add_submacro(const symbol::Symbol& s, Macro* macro);
+
 private :
     std::list<symbol::Variable*>*   m_inputArgs;
     std::list<symbol::Variable*>*   m_outputArgs;
@@ -93,7 +95,7 @@ private :
     symbol::Variable*               m_Varargout;
     Double*                         m_pDblArgIn;
     Double*                         m_pDblArgOut;
-
+    std::map<symbol::Variable*, Macro*> m_submacro;
 };
 }
 
index 2bfb6f6..3f1868b 100644 (file)
@@ -69,6 +69,14 @@ Macro::~Macro()
     {
         delete m_outputArgs;
     }
+
+for (const auto & sub : m_submacro)
+    {
+        sub.second->DecreaseRef();
+        sub.second->killMe();
+    }
+
+    m_submacro.clear();
 }
 
 void Macro::cleanCall(symbol::Context * pContext, int oldPromptMode)
@@ -282,6 +290,13 @@ Callable::ReturnValue Macro::call(typed_list &in, optional_list &opt, int _iRetC
     pContext->put(m_Nargin, m_pDblArgIn);
     pContext->put(m_Nargout, m_pDblArgOut);
 
+
+    //add sub macro in current context
+for (const auto & sub : m_submacro)
+    {
+        pContext->put(sub.first, sub.second);
+    }
+
     //save current prompt mode
     int oldVal = ConfigVariable::getPromptMode();
     try
@@ -491,4 +506,12 @@ bool Macro::operator==(const InternalType& it)
 
     return ret;
 }
+
+void Macro::add_submacro(const symbol::Symbol& s, Macro* macro)
+{
+    macro->IncreaseRef();
+    symbol::Context* ctx = symbol::Context::getInstance();
+    symbol::Variable* var = ctx->getOrCreate(s);
+    m_submacro[var] = macro;
+}
 }
index 04704fe..34254f2 100644 (file)
@@ -93,6 +93,7 @@ bool MacroFile::parse(void)
 
         ast::exps_t::iterator j;
         ast::exps_t LExp = tree->getAs<ast::SeqExp>()->getExps();
+        std::map<symbol::Symbol, Macro*> sub;
 
         for (j = LExp.begin() ; j != LExp.end() ; j++)
         {
@@ -102,41 +103,65 @@ bool MacroFile::parse(void)
             }
 
             pFD = (*j)->getAs<ast::FunctionDec>();
-            if (pFD) // &&     pFD->getName() == m_stName
+
+            //get input parameters list
+            std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
+            ast::ArrayListVar *pListVar = pFD->getArgs().getAs<ast::ArrayListVar>();
+            ast::exps_t & vars = pListVar->getVars();
+            for (ast::exps_t::const_iterator it = vars.begin(), itEnd = vars.end(); it != itEnd; ++it)
+            {
+                pVarList->push_back((*it)->getAs<ast::SimpleVar>()->getStack());
+            }
+
+            //get output parameters list
+            std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
+            ast::ArrayListVar *pListRet = pFD->getReturns().getAs<ast::ArrayListVar>();
+            ast::exps_t & recs = pListRet->getVars();
+            for (ast::exps_t::const_iterator it = recs.begin(), itEnd = recs.end(); it != itEnd; ++it)
             {
-                symbol::Context* pContext = symbol::Context::getInstance();
-                InternalType* pFunc = pContext->getFunction(pFD->getSymbol());
-                if (pFunc && pFunc->isMacroFile())
+                pRetList->push_back((*it)->getAs<ast::SimpleVar>()->getStack());
+            }
+
+            const symbol::Symbol & sym = pFD->getSymbol();
+            Macro* macro = new Macro(sym.getName(), *pVarList, *pRetList, (ast::SeqExp&)pFD->getBody(), m_wstModule);
+            macro->setFirstLine(pFD->getLocation().first_line);
+
+            if (m_pMacro == nullptr && sym.getName() == getName())
+            {
+                //we found the main macro
+                m_pMacro = macro;
+            }
+            else
+            {
+                //we found a sub macro
+                if (sub.find(sym) == sub.end())
                 {
-                    MacroFile* pMacro = pContext->getFunction(pFD->getSymbol())->getAs<MacroFile>();
-                    if (pMacro->m_pMacro == NULL)
-                    {
-
-                        //get input parameters list
-                        std::list<symbol::Variable*> *pVarList = new std::list<symbol::Variable*>();
-                        ast::ArrayListVar *pListVar = pFD->getArgs().getAs<ast::ArrayListVar>();
-                        ast::exps_t vars = pListVar->getVars();
-                        for (ast::exps_t::const_iterator it = vars.begin(), itEnd = vars.end() ; it != itEnd ; ++it)
-                        {
-                            pVarList->push_back((*it)->getAs<ast::SimpleVar>()->getStack());
-                        }
-
-                        //get output parameters list
-                        std::list<symbol::Variable*> *pRetList = new std::list<symbol::Variable*>();
-                        ast::ArrayListVar *pListRet = pFD->getReturns().getAs<ast::ArrayListVar>();
-                        ast::exps_t recs = pListRet->getVars();
-                        for (ast::exps_t::const_iterator it = recs.begin(), itEnd = recs.end(); it != itEnd ; ++it)
-                        {
-                            pRetList->push_back((*it)->getAs<ast::SimpleVar>()->getStack());
-                        }
-
-                        pMacro->m_pMacro = new Macro(m_wstName, *pVarList, *pRetList, (ast::SeqExp&)pFD->getBody(), m_wstModule);
-                        pMacro->setFirstLine(pFD->getLocation().first_line);
-                    }
+                    sub[sym] = macro;
                 }
+                else
+                {
+                    // This macro is a doublon !!
+                    delete macro;
+                }
+            }
+        }
+
+        if (m_pMacro)
+        {
+            for (const auto & macro : sub)
+            {
+                m_pMacro->add_submacro(macro.first, macro.second);
+            }
+        }
+        else
+        {
+            // This is an incorrect library => we should not be here !
+            for (const auto & macro : sub)
+            {
+                delete macro.second;
             }
-            delete *j;
         }
+        sub.clear();
 
         ((ast::SeqExp*)tree)->clearExps();
         delete tree;
index f94d999..8fa1cdc 100644 (file)
@@ -46,3 +46,15 @@ lib1lib = lib("lib1");
 assert_checkequal(lib1lib.lib_test(), "lib1");
 lib2lib = lib("lib2");
 assert_checkequal(lib2lib.lib_test(), "lib2");
+m = mgetl("SCI/modules/ast/tests/unit_tests/test_macro.sci");
+mkdir("test");
+mputl(m, "test/test_macro.sci");
+genlib("testlib","test",%f,%t);
+-- Creation of [testlib] (Macros) --
+assert_checkequal(test_macro(4), 16);
+assert_checkequal(exists("internal_macro"), 0);
+assert_checkequal(exists("x"), 0);
+internal_macro = 1;x = 18;
+assert_checkequal(test_macro(5), 20);
+assert_checkequal(internal_macro, 1);
+assert_checkequal(x, 18);
index 3e59559..10e3b39 100644 (file)
@@ -51,3 +51,17 @@ lib1lib = lib("lib1");
 assert_checkequal(lib1lib.lib_test(), "lib1");
 lib2lib = lib("lib2");
 assert_checkequal(lib2lib.lib_test(), "lib2");
+
+
+m = mgetl("SCI/modules/ast/tests/unit_tests/test_macro.sci");
+mkdir("test");
+mputl(m, "test/test_macro.sci");
+genlib("testlib","test",%f,%t);
+assert_checkequal(test_macro(4), 16);
+assert_checkequal(exists("internal_macro"), 0);
+assert_checkequal(exists("x"), 0);
+
+internal_macro = 1;x = 18;
+assert_checkequal(test_macro(5), 20);
+assert_checkequal(internal_macro, 1);
+assert_checkequal(x, 18);
diff --git a/scilab/modules/ast/tests/unit_tests/test_macro.sci b/scilab/modules/ast/tests/unit_tests/test_macro.sci
new file mode 100644 (file)
index 0000000..425586f
--- /dev/null
@@ -0,0 +1,21 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2015 - Scilab Enterprises - Antoine ELIAS
+//
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution.  The terms
+// are also available at
+// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+
+function ret = test_macro(a, x)
+    assert_checkequal(typeof(x), "function");
+    ret = internal_macro(a) * 2;
+endfunction
+
+function ret = internal_macro(a)
+    ret = a * 2;
+endfunction
+
+function ret = x()
+    //nothing
+endfunction
\ No newline at end of file
index 3802521..a23ab08 100644 (file)
@@ -198,13 +198,18 @@ Function::ReturnValue sci_genlib(types::typed_list &in, int _iRetCount, types::t
                 if ((*j)->isFunctionDec())
                 {
                     ast::FunctionDec* pFD = (*j)->getAs<ast::FunctionDec>();
-                    if (AddMacroToXML(pWriter, pair<wstring, wstring>(pFD->getSymbol().getName(), pstPathBin)) == false)
+                    const wstring& name = pFD->getSymbol().getName();
+                    if (name + L".sci" == pstPath[k])
                     {
-                        os_swprintf(pstVerbose, 65535, _W("%ls: Warning: %ls information cannot be added to file %ls. File ignored\n").c_str(), L"genlib", pFD->getSymbol().getName().c_str(), pstPath[k]);
-                        scilabWriteW(pstVerbose);
+                        if (AddMacroToXML(pWriter, pair<wstring, wstring>(name, pstPathBin)) == false)
+                        {
+                            os_swprintf(pstVerbose, 65535, _W("%ls: Warning: %ls information cannot be added to file %ls. File ignored\n").c_str(), L"genlib", pFD->getSymbol().getName().c_str(), pstPath[k]);
+                            scilabWriteW(pstVerbose);
+                        }
+
+                        pLib->add(name, new types::MacroFile(name, stFullPathBin, pstLibName));
+                        break;
                     }
-
-                    pLib->add(pFD->getSymbol().getName(), new types::MacroFile(pFD->getSymbol().getName(), stFullPathBin, pstLibName));
                 }
             }