* bug #14801 fixed: [cells1 cells2] puzzled cells components 29/19029/6
Samuel GOUGEON [Sat, 8 Oct 2016 15:48:46 +0000 (17:48 +0200)]
 * http://bugzilla.scilab.org/14801
 * Remove concatenation overload for cells.
 * Manage as matrix
 * test_run data_structures passed
   test_run overloading passed
   test_run ast concatenation

Change-Id: I115d4c135f7297f44e45f7492a2b07265ad8c535

scilab/CHANGES.md
scilab/modules/ast/src/cpp/ast/visitor_common.cpp
scilab/modules/ast/tests/nonreg_tests/bug_14801.tst [new file with mode: 0644]
scilab/modules/ast/tests/unit_tests/concatenation.dia.ref [deleted file]
scilab/modules/ast/tests/unit_tests/concatenation.tst
scilab/modules/overloading/macros/%ce_c_ce.sci [deleted file]
scilab/modules/overloading/macros/%ce_f_ce.sci [deleted file]

index 397a0e0..5a97db7 100644 (file)
@@ -445,6 +445,7 @@ Bug Fixes
 * [#14784](http://bugzilla.scilab.org/show_bug.cgi?id=14784): Setting field of graphics handle using children($) failed.
 * [#14796](http://bugzilla.scilab.org/show_bug.cgi?id=14796): `ind2sub(dims, [])` returned [] in version 6. Warnings due to a `[]+1` operation occurred
 * [#14775](http://bugzilla.scilab.org/show_bug.cgi?id=14775): Loading empty (0 bytes) .sod File crashed scilab
+* [#14801](http://bugzilla.scilab.org/show_bug.cgi?id=14801): The horizontal concatenation of cells arrays wrongly puzzled components.
 * [#14808](http://bugzilla.scilab.org/show_bug.cgi?id=14808): E=[ 'A' 'B' 'C' 'D' 'E']  ,  E(0:0) Crash Scilab Console
 * [#14821](http://bugzilla.scilab.org/show_bug.cgi?id=14821): `getio` function was missing. An error on the diary file opened has been corrected
 * [#14824](http://bugzilla.scilab.org/show_bug.cgi?id=14824): Incorrect error message with `mfprintf(fd, "%d", [])`.
index 36c6111..de9e957 100644 (file)
@@ -42,7 +42,7 @@ size_t ast::Ast::globalNodeNumber = 0;
 /*
  * Generate destination variable from _poSource type and size parameters
  */
-types::InternalType* allocDest(types::InternalType* _poSource, int _iRows, int _iCols)
+static types::InternalType* allocDest(types::InternalType* _poSource, int _iRows, int _iCols)
 {
     types::InternalType* poResult = NULL;
     switch (_poSource->getType())
@@ -77,10 +77,13 @@ types::InternalType* allocDest(types::InternalType* _poSource, int _iRows, int _
         case types::InternalType::ScilabUInt64 :
             poResult = new types::UInt64(_iRows, _iCols);
             break;
-        case types::InternalType::ScilabString :
+        case types::InternalType::ScilabString:
             poResult = new types::String(_iRows, _iCols);
             break;
-        case types::InternalType::ScilabPolynom :
+        case types::InternalType::ScilabCell:
+            poResult = new types::Cell(_iRows, _iCols);
+            break;
+        case types::InternalType::ScilabPolynom:
         {
             int* piRank = new int[_iRows * _iCols];
             memset(piRank, 0x00, _iRows * _iCols * sizeof(int));
@@ -255,10 +258,13 @@ types::InternalType* AddElementToVariable(types::InternalType* _poDest, types::I
             case types::InternalType::ScilabImplicitList :
                 poResult = new types::ImplicitList();
                 break;
-            case types::InternalType::ScilabHandle :
+            case types::InternalType::ScilabHandle:
                 poResult = new types::GraphicHandle(_iRows, _iCols);
                 break;
-            default :
+            case types::InternalType::ScilabCell:
+                poResult = new types::Cell(_iRows, _iCols);
+                break;
+            default:
                 // FIXME What should we do here ...
                 break;
         }
@@ -509,12 +515,13 @@ types::InternalType* AddElementToVariable(types::InternalType* _poDest, types::I
             case types::InternalType::ScilabSparseBool :
                 poResult->getAs<types::SparseBool>()->append(iCurRow, iCurCol, _poSource->getAs<types::SparseBool>());
                 break;
-            case types::InternalType::ScilabString :
-            {
+            case types::InternalType::ScilabString:
                 poResult->getAs<types::String>()->append(iCurRow, iCurCol, _poSource);
-            }
-            break;
-            case types::InternalType::ScilabImplicitList :
+                break;
+            case types::InternalType::ScilabCell:
+                poResult->getAs<types::Cell>()->append(iCurRow, iCurCol, _poSource);
+                break;
+            case types::InternalType::ScilabImplicitList:
             {
                 types::ImplicitList* pIL = _poSource->getAs<types::ImplicitList>();
                 types::ImplicitList* pOL = poResult->getAs<types::ImplicitList>();
diff --git a/scilab/modules/ast/tests/nonreg_tests/bug_14801.tst b/scilab/modules/ast/tests/nonreg_tests/bug_14801.tst
new file mode 100644 (file)
index 0000000..6623417
--- /dev/null
@@ -0,0 +1,30 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2016 - Samuel GOUGEON
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// <-- Non-regression test for bug 14801 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/14801
+//
+// <-- Short Description -->
+// The horizontal concatenation of cells arrays misworked
+
+a = {[1;-0.5],[]; 0.3, 1};
+b = {"test"; %z};
+r = [a b];
+assert_checkequal(r{1,2}, a{1,2});
+assert_checkequal(r{2,1}, a{2,1});
+assert_checkequal(r{1,3}, b{1,1});
+
+A = cat(3,a,a);
+B = cat(3,b,b);
+R = [A B];
+assert_checkequal(R{1,2,2}, a{1,2});
+assert_checkequal(R{2,1,2}, a{2,1});
+assert_checkequal(R{1,3,2}, b{1,1});
diff --git a/scilab/modules/ast/tests/unit_tests/concatenation.dia.ref b/scilab/modules/ast/tests/unit_tests/concatenation.dia.ref
deleted file mode 100644 (file)
index 8927e0f..0000000
+++ /dev/null
@@ -1,193 +0,0 @@
-// ============================================================================
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) 2014 - Scilab Enterprises - Cedric Delamarre
-//
-//  This file is distributed under the same license as the Scilab package.
-// ============================================================================
-// <-- CLI SHELL MODE -->
-function checkCallOverload(mat)
-    assert_checkerror(mat, [], 999);
-endfunction
-ldouble = [1 2 3];
-lbool   = [%t %f %t];
-lint    = [int32(1) int32(2) int32(3)];
-lint16  = [int16(1) int16(2) int16(3)];
-lpoly   = [%s %s^2 %s];
-lsparse = [sparse(1) sparse(2) sparse(3)];
-lspb    = [sparse(%t) sparse(%f) sparse(%t)];
-lstring = ["Scilab" "Enterprises" "2014"];
-sta.x   = 12;
-lsta    = [sta sta sta];
-// list, tlist, mlist
-checkCallOverload("[list(1) list(2)]");
-// Double
-assert_checkequal([ldouble ldouble], [1 2 3 1 2 3]);
-assert_checkequal([ldouble lbool], [ldouble double(lbool)]);
-checkCallOverload("[ldouble lint]");
-checkCallOverload("[ldouble lint16]");
-assert_checkequal([ldouble lpoly], [(ldouble + 0*%s) lpoly]);
-assert_checkequal([ldouble lsparse], [sparse(ldouble) lsparse]);
-checkCallOverload("[ldouble lspb]");
-checkCallOverload("[ldouble lstring]");
-checkCallOverload("[ldouble lsta]");
-assert_checkequal([ldouble ; ldouble], matrix([1 1 2 2 3 3], 2, 3));
-assert_checkequal([ldouble ; lbool], [ldouble ; double(lbool)]);
-checkCallOverload("[ldouble ; lint]");
-checkCallOverload("[ldouble ; lint16]");
-assert_checkequal([ldouble ; lpoly], [(ldouble + 0*%s) ; lpoly]);
-assert_checkequal([ldouble ; lsparse], [sparse(ldouble) ; lsparse]);
-checkCallOverload("[ldouble ; lspb]");
-checkCallOverload("[ldouble ; lstring]");
-checkCallOverload("[ldouble ; lsta]");
-// Bool
-assert_checkequal([lbool ldouble], [double(lbool) ldouble]);
-assert_checkequal([lbool lbool], [%t %f %t %t %f %t]);
-checkCallOverload("[lbool lint]");
-checkCallOverload("[lbool lint16]");
-checkCallOverload("[lbool lpoly]");
-checkCallOverload("[lbool lsparse]");
-assert_checkequal([lbool lspb], [sparse(lbool) lspb]);
-checkCallOverload("[lbool lstring]");
-checkCallOverload("[lbool lsta]");
-assert_checkequal([lbool ; ldouble], [double(lbool) ; ldouble]);
-assert_checkequal([lbool ; lbool], matrix([%t %t %f %f %t %t], 2, 3));
-checkCallOverload("[lbool ; lint]");
-checkCallOverload("[lbool ; lint16]");
-checkCallOverload("[lbool ; lpoly]");
-checkCallOverload("[lbool ; lsparse]");
-assert_checkequal([lbool ; lspb], [sparse(lbool) ; lspb]);
-checkCallOverload("[lbool ; lstring]");
-checkCallOverload("[lbool ; lsta]");
-// int
-checkCallOverload("[lint ldouble]");
-checkCallOverload("[lint lbool]");
-assert_checkequal([lint lint], int32([1 2 3 1 2 3]));
-checkCallOverload("[lint lint16]");
-checkCallOverload("[lint lpoly]");
-checkCallOverload("[lint lsparse]");
-checkCallOverload("[lint lspb]");
-checkCallOverload("[lint lstring]");
-checkCallOverload("[lint lsta]");
-checkCallOverload("[lint ; ldouble]");
-checkCallOverload("[lint ; lbool]");
-assert_checkequal([lint ; lint], int32(matrix([1 1 2 2 3 3], 2, 3)));
-checkCallOverload("[lint ; lint16]");
-checkCallOverload("[lint ; lpoly]");
-checkCallOverload("[lint ; lsparse]");
-checkCallOverload("[lint ; lspb]");
-checkCallOverload("[lint  lstring]");
-checkCallOverload("[lint ; lsta]");
-// polynom
-assert_checkequal([lpoly ldouble], [%s %s^2 %s 1 2 3]);
-checkCallOverload("[lpoly lbool]");
-checkCallOverload("[lpoly lint]");
-checkCallOverload("[lpoly lint16]");
-assert_checkequal([lpoly lpoly], [%s %s^2 %s %s %s^2 %s]);
-checkCallOverload("[lpoly lsparse]");
-checkCallOverload("[lpoly lspb]");
-checkCallOverload("[lpoly lstring]");
-checkCallOverload("[lpoly lsta]");
-assert_checkequal([lpoly ; ldouble], matrix([%s 1 %s^2 2 %s 3], 2, 3));
-checkCallOverload("[lpoly ; lbool]");
-checkCallOverload("[lpoly ; lint]");
-checkCallOverload("[lpoly ; lint16]");
-assert_checkequal([lpoly ; lpoly], matrix([%s %s %s^2 %s^2 %s %s], 2, 3));
-checkCallOverload("[lpoly ; lsparse]");
-checkCallOverload("[lpoly ; lspb]");
-checkCallOverload("[lpoly ; lstring]");
-checkCallOverload("[lpoly ; lsta]");
-// sparse
-assert_checkequal([lsparse ldouble], sparse([1 2 3 1 2 3]));
-checkCallOverload("[lsparse lbool]");
-checkCallOverload("[lsparse lint]");
-checkCallOverload("[lsparse lint16]");
-checkCallOverload("[lsparse lpoly]");
-assert_checkequal([lsparse lsparse], sparse([1 2 3 1 2 3]));
-checkCallOverload("[lsparse lspb]");
-checkCallOverload("[lsparse lstring]");
-checkCallOverload("[lsparse lsta]");
-assert_checkequal([lsparse ; ldouble], sparse(matrix([1 1 2 2 3 3], 2, 3)));
-checkCallOverload("[lsparse  ;lbool]");
-checkCallOverload("[lsparse ; lint]");
-checkCallOverload("[lsparse ; lint16]");
-checkCallOverload("[lsparse ; lpoly]");
-assert_checkequal([lsparse ; lsparse], sparse(matrix([1 1 2 2 3 3], 2, 3)));
-checkCallOverload("[lsparse ; lspb]");
-checkCallOverload("[lsparse ; lstring]");
-checkCallOverload("[lsparse ; lsta]");
-// boolean sparse
-checkCallOverload("[lspb ldouble]");
-assert_checkequal([lspb lbool], sparse([%t %f %t %t %f %t]));
-checkCallOverload("[lspb lint]");
-checkCallOverload("[lspb lint16]");
-checkCallOverload("[lspb lpoly]");
-checkCallOverload("[lspb lsparse]");
-assert_checkequal([lspb lspb], sparse([%t %f %t %t %f %t]));
-checkCallOverload("[lspb lstring]");
-checkCallOverload("[lspb lsta]");
-checkCallOverload("[lspb ; ldouble]");
-assert_checkequal([lspb ; lbool], sparse(matrix([%t %t %f %f %t %t], 2 ,3)));
-checkCallOverload("[lspb ; lint]");
-checkCallOverload("[lspb ; lint16]");
-checkCallOverload("[lspb ; lpoly]");
-checkCallOverload("[lspb ; lsparse]");
-assert_checkequal([lspb ; lspb], sparse(matrix([%t %t %f %f %t %t], 2 ,3)));
-checkCallOverload("[lspb ; lstring]");
-checkCallOverload("[lspb ; lsta]");
-// string
-checkCallOverload("[lstring ldouble]");
-checkCallOverload("[lstring lbool]");
-checkCallOverload("[lstring lint]");
-checkCallOverload("[lstring lint16]");
-checkCallOverload("[lstring lpoly]");
-checkCallOverload("[lstring lsparse]");
-checkCallOverload("[lstring lspb]");
-assert_checkequal([lstring lstring], ["Scilab" "Enterprises" "2014" "Scilab" "Enterprises" "2014"]);
-checkCallOverload("[lstring lsta]");
-checkCallOverload("[lstring ; ldouble]");
-checkCallOverload("[lstring ; lbool]");
-checkCallOverload("[lstring ; lint]");
-checkCallOverload("[lstring ; lint16]");
-checkCallOverload("[lstring ; lpoly]");
-checkCallOverload("[lstring ; lsparse]");
-checkCallOverload("[lstring ; lspb]");
-assert_checkequal([lstring ; lstring], matrix(["Scilab" "Scilab" "Enterprises" "Enterprises" "2014" "2014"], 2, 3));
-checkCallOverload("[lstring ; lsta]");
-// struct
-stb.y = 23;
-stc.x = 56;
-lstb  = [stb stb stb];
-lstc  = [stc stc stc];
-checkCallOverload("[lsta ldouble]");
-checkCallOverload("[lsta lbool]");
-checkCallOverload("[lsta lint]");
-checkCallOverload("[lsta lint16]");
-checkCallOverload("[lsta lpoly]");
-checkCallOverload("[lsta lsparse]");
-checkCallOverload("[lsta lspb]");
-checkCallOverload("[lsta lstring]");
-assert_checkequal([lsta lsta], [sta sta sta sta sta sta]);
-assert_checkerror("[lsta ; lstb]", msprintf(_("%s: Field names mismatch.\n"),"%st_c_st"), 10000);
-checkCallOverload("[lsta ; ldouble]");
-checkCallOverload("[lsta ; lbool]");
-checkCallOverload("[lsta ; lint]");
-checkCallOverload("[lsta ; lint16]");
-checkCallOverload("[lsta ; lpoly]");
-checkCallOverload("[lsta ; lsparse]");
-checkCallOverload("[lsta ; lspb]");
-checkCallOverload("[lsta ; lstring]");
-assert_checkequal([lsta ; lsta], matrix([sta sta sta sta sta sta], 2, 3));
-assert_checkerror("[lsta ; lstb]", msprintf(_("%s: Field names mismatch.\n"),"%st_c_st"), 10000);
-// ImplicitList
-checkCallOverload("[1:$ 2]");
-checkCallOverload("[1:$ 1:2]");
-checkCallOverload("[1:$ int8(2)]");
-checkCallOverload("[1:2 1:$]");
-checkCallOverload("[1:$ 1:$]");
-assert_checkequal([1:3 1:3], [1 2 3 1 2 3]);
-checkCallOverload("[1:$ ; 2]");
-checkCallOverload("[1:$ ; 1:2]");
-checkCallOverload("[1:$ ; int8(2)]");
-checkCallOverload("[1:2 ; 1:$]");
-checkCallOverload("[1:$ ; 1:$]");
-assert_checkequal([1:3 ; 1:3], matrix([1 1 2 2 3 3], 2, 3));
index c2334b1..34a4080 100644 (file)
@@ -6,6 +6,7 @@
 // ============================================================================
 
 // <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
 
 function checkCallOverload(mat)
     assert_checkerror(mat, [], 999);
@@ -21,6 +22,7 @@ lspb    = [sparse(%t) sparse(%f) sparse(%t)];
 lstring = ["Scilab" "Enterprises" "2014"];
 sta.x   = 12;
 lsta    = [sta sta sta];
+lcell   = {ldouble, lbool, lstring};
 
 // list, tlist, mlist
 checkCallOverload("[list(1) list(2)]");
@@ -215,3 +217,80 @@ checkCallOverload("[1:2 ; 1:$]");
 checkCallOverload("[1:$ ; 1:$]");
 assert_checkequal([1:3 ; 1:3], matrix([1 1 2 2 3 3], 2, 3));
 
+//cells
+
+//row
+c = [lcell,lcell];
+assert_checkequal(c, {ldouble, lbool, lstring, ldouble, lbool, lstring});
+assert_checkequal(c{1, 1}, ldouble);
+assert_checkequal(c{1, 2}, lbool);
+assert_checkequal(c{1, 3}, lstring);
+assert_checkequal(c{1, 4}, ldouble);
+assert_checkequal(c{1, 5}, lbool);
+assert_checkequal(c{1, 6}, lstring);
+
+//col
+c = [lcell;lcell];
+assert_checkequal(c, {ldouble, lbool, lstring;ldouble, lbool, lstring});
+assert_checkequal(c{1, 1}, ldouble);
+assert_checkequal(c{1, 2}, lbool);
+assert_checkequal(c{1, 3}, lstring);
+assert_checkequal(c{2, 1}, ldouble);
+assert_checkequal(c{2, 2}, lbool);
+assert_checkequal(c{2, 3}, lstring);
+
+//2d
+c = [lcell,lcell;lcell,lcell;lcell,lcell];
+assert_checkequal(c(1, 1:3), lcell);
+assert_checkequal(c(1, 4:6), lcell);
+assert_checkequal(c(2, 1:3), lcell);
+assert_checkequal(c(2, 4:6), lcell);
+assert_checkequal(c(3, 1:3), lcell);
+assert_checkequal(c(3, 4:6), lcell);
+
+c_2_4 = {ldouble, lbool, lstring, lcell;lcell, lstring, lbool, ldouble};
+c_2_2 = {ldouble, lbool;lstring, lcell}
+c = [c_2_4;c_2_2,c_2_2];
+assert_checkequal(c{1, 1}, ldouble);
+assert_checkequal(c{1, 2}, lbool);
+assert_checkequal(c{1, 3}, lstring);
+assert_checkequal(c{1, 4}, lcell);
+assert_checkequal(c{2, 1}, lcell);
+assert_checkequal(c{2, 2}, lstring);
+assert_checkequal(c{2, 3}, lbool);
+assert_checkequal(c{2, 4}, ldouble);
+assert_checkequal(c{3, 1}, ldouble);
+assert_checkequal(c{3, 2}, lbool);
+assert_checkequal(c{3, 3}, ldouble);
+assert_checkequal(c{3, 4}, lbool);
+assert_checkequal(c{4, 1}, lstring);
+assert_checkequal(c{4, 2}, lcell);
+assert_checkequal(c{4, 3}, lstring);
+assert_checkequal(c{4, 4}, lcell);
+
+//3d
+c1 = {ldouble, lbool;lstring, lcell};
+c2 = {lpoly;lsta};
+C1(:,:,2) = c1;
+C1(:,:,1) = c1;
+C2(:,:,2) = c2;
+C2(:,:,1) = c2;
+R = [C1;C2 C2];
+assert_checkequal(R{1,1,1}, C1{1,1,1});
+assert_checkequal(R{1,1,2}, C1{1,1,2});
+assert_checkequal(R{1,2,1}, C1{1,2,1});
+assert_checkequal(R{1,2,2}, C1{1,2,2});
+assert_checkequal(R{2,1,1}, C1{2,1,1});
+assert_checkequal(R{2,1,2}, C1{2,1,2});
+assert_checkequal(R{2,2,1}, C1{2,2,1});
+assert_checkequal(R{2,2,2}, C1{2,2,2});
+
+assert_checkequal(R{3,1,1}, C2{1,1,1});
+assert_checkequal(R{3,1,2}, C2{1,1,2});
+assert_checkequal(R{3,2,1}, C2{1,1,1});
+assert_checkequal(R{3,2,2}, C2{1,1,2});
+
+assert_checkequal(R{4,1,1}, C2{2,1,1});
+assert_checkequal(R{4,1,2}, C2{2,1,2});
+assert_checkequal(R{4,2,1}, C2{2,1,1});
+assert_checkequal(R{4,2,2}, C2{2,1,2});
diff --git a/scilab/modules/overloading/macros/%ce_c_ce.sci b/scilab/modules/overloading/macros/%ce_c_ce.sci
deleted file mode 100644 (file)
index d97c90f..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) INRIA
-//
-// 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.
-
-function r=%ce_c_ce(a,b)
-    da = size(a);
-    if size(da,"*") < 2 then
-        da(2) = 1;
-    end
-    db = size(b);
-    if size(db,"*") < 2 then
-        db(2) = 1;
-    end
-    if size(da,"*") <> size(db,"*") then
-        error(msprintf(_("%s: In concatenation the number of dimensions for each component must match.\n"),"ce_c_ce"));
-    end
-
-    kd = find(da<>db);
-    kd(find(kd==2)) = [];
-    if kd <> [] then
-        error(5);
-    end
-    v = [matrix(1:prod(da),da(1)*da(2),prod(da)/(da(1)*da(2)));
-    -matrix(1:prod(db),db(1)*db(2),prod(db)/(db(1)*db(2)))];
-    val = list();
-    for k = 1:size(v,"*")
-        if v(k) > 0 then
-            val(k) = a{v(k)};
-        else
-            val(k) = b{-v(k)};
-        end
-    end
-    da(2) = da(2)+db(2);
-    r = makecell(da, val(:));
-endfunction
-
-
-
diff --git a/scilab/modules/overloading/macros/%ce_f_ce.sci b/scilab/modules/overloading/macros/%ce_f_ce.sci
deleted file mode 100644 (file)
index 7716025..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
-// Copyright (C) INRIA
-//
-// 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.
-
-function R=%ce_f_ce(M1,M2)
-    //R=[M1' M2']'
-    R=%ce_t(%ce_c_ce(%ce_t(M1),%ce_t(M2)))
-endfunction
-
-
-