diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp
index 1a06cc399b4b006f110e204560a035b6dfdd968a..5937d6c600ffb6f27dd2a4ba732136b52e0725c9 100644
--- a/Geo/GModelIO_OCC.cpp
+++ b/Geo/GModelIO_OCC.cpp
@@ -25,6 +25,7 @@
 #include <BRepBuilderAPI_MakeFace.hxx>
 #include <BRepBuilderAPI_Copy.hxx>
 #include <BRepPrimAPI_MakePrism.hxx>
+#include <BRepPrimAPI_MakeRevol.hxx>
 #include <BRepOffsetAPI_ThruSections.hxx>
 #include <gce_MakeCirc.hxx>
 #include <gce_MakePln.hxx>
@@ -804,9 +805,10 @@ void OCC_Internals::addThruSections(int tag, std::vector<int> wireTags)
   bind(result, tag);
 }
 
-void OCC_Internals::extrude(int tag, std::vector<int> inTags[4],
-                            double dx, double dy, double dz,
-                            std::vector<int> outTags[4])
+void OCC_Internals::_extrudeRevolve(int tag, bool revolve, std::vector<int> inTags[4],
+                                    double x, double y, double z,
+                                    double dx, double dy, double dz, double angle,
+                                    std::vector<int> outTags[4])
 {
   for(int dim = 0; dim < 3; dim++){
     if(tag > 0 && inTags[dim].size() && isBound(tag, dim + 1)){
@@ -816,6 +818,11 @@ void OCC_Internals::extrude(int tag, std::vector<int> inTags[4],
     }
   }
 
+  // build a single compound shape, so that we won't duplicate internal
+  // boundaries
+  BRep_Builder b;
+  TopoDS_Compound c;
+  b.MakeCompound(c);
   for(int dim = 0; dim < 4; dim++){
     for(unsigned int i = 0; i < inTags[dim].size(); i++){
       if(!isBound(dim, inTags[dim][i])){
@@ -824,16 +831,52 @@ void OCC_Internals::extrude(int tag, std::vector<int> inTags[4],
         return;
       }
       TopoDS_Shape shape = find(dim, inTags[dim][i]);
-      BRepPrimAPI_MakePrism p(shape, gp_Vec(dx, dy, dz), Standard_False);
+      b.Add(c, shape);
+    }
+  }
+  TopoDS_Shape result;
+  try{
+    if(revolve){
+      gp_Ax1 axisOfRevolution(gp_Pnt(x, y, z), gp_Dir(dx, dy, dz));
+      BRepPrimAPI_MakeRevol r(c, axisOfRevolution, angle, Standard_False);
+      r.Build();
+      if(!r.IsDone()){
+        Msg::Error("Could not revolve");
+        return;
+      }
+      result = r.Shape();
+    }
+    else{
+      BRepPrimAPI_MakePrism p(c, gp_Vec(dx, dy, dz), Standard_False);
       p.Build();
       if(!p.IsDone()){
         Msg::Error("Could not extrude");
         return;
       }
-      TopoDS_Shape result = p.Shape();
-      bind(result, true, tag, outTags);
+      result = p.Shape();
     }
   }
+  catch(Standard_Failure &err){
+    Msg::Error("OpenCASCADE exception %s", err.GetMessageString());
+    return;
+  }
+
+  bind(result, true, tag, outTags);
+}
+
+void OCC_Internals::extrude(int tag, std::vector<int> inTags[4],
+                            double dx, double dy, double dz,
+                            std::vector<int> outTags[4])
+{
+  _extrudeRevolve(tag, false, inTags, 0, 0, 0, dx, dy, dz, 0, outTags);
+}
+
+void OCC_Internals::revolve(int tag, std::vector<int> inTags[4],
+                            double x, double y, double z,
+                            double dx, double dy, double dz, double angle,
+                            std::vector<int> outTags[4])
+{
+  _extrudeRevolve(tag, true, inTags, x, y, z, dx, dy, dz, angle, outTags);
 }
 
 void OCC_Internals::applyBooleanOperator(int tag, BooleanOperator op,
diff --git a/Geo/GModelIO_OCC.h b/Geo/GModelIO_OCC.h
index 7bf36f1bbf77a6b1e242603517f115cffe8ddf4a..a70bf42e6f138eccff2d2509f34c25f6320ae897 100644
--- a/Geo/GModelIO_OCC.h
+++ b/Geo/GModelIO_OCC.h
@@ -49,6 +49,12 @@ class OCC_Internals {
   // add bezier or bspline
   void _addSpline(int tag, std::vector<int> vertexTags, int mode);
 
+  // extrude or revolve
+  void _extrudeRevolve(int tag, bool revolve, std::vector<int> inTags[4],
+                       double x, double y, double z,
+                       double dx, double dy, double dz, double angle,
+                       std::vector<int> outTags[4]);
+
  public:
   OCC_Internals();
 
@@ -108,10 +114,13 @@ class OCC_Internals {
                    double x2, double y2, double z2, double r);
   void addThruSections(int tag, std::vector<int> wireTags);
 
-  // extrusion
+  // extrusion and revolution
   void extrude(int tag, std::vector<int> inTags[4],
                double dx, double dy, double dz,
                std::vector<int> outTags[4]);
+  void revolve(int tag, std::vector<int> inTags[4],
+               double x, double y, double z, double dx, double dy, double dz,
+               double angle, std::vector<int> outTags[4]);
 
   // apply boolean operator
   void applyBooleanOperator(int tag, BooleanOperator op,
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index 29955384bead8f8cb5cbd85b3eb52236b59c8180..57fbf50c85cf2d0b3ad6f9d20a781bacbca17bc9 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -1390,37 +1390,37 @@ static const yytype_uint16 yyrline[] =
     3537,  3599,  3617,  3634,  3649,  3678,  3690,  3714,  3718,  3723,
     3731,  3736,  3742,  3747,  3753,  3761,  3765,  3769,  3774,  3834,
     3850,  3867,  3884,  3906,  3928,  3963,  3971,  3979,  3985,  3992,
-    3999,  4019,  4045,  4057,  4069,  4099,  4107,  4116,  4115,  4130,
-    4129,  4144,  4143,  4158,  4157,  4171,  4178,  4185,  4192,  4199,
-    4206,  4213,  4220,  4227,  4235,  4234,  4248,  4247,  4261,  4260,
-    4274,  4273,  4287,  4286,  4300,  4299,  4313,  4312,  4326,  4325,
-    4339,  4338,  4355,  4358,  4364,  4376,  4396,  4420,  4424,  4428,
-    4432,  4436,  4440,  4446,  4452,  4456,  4460,  4464,  4468,  4487,
-    4500,  4501,  4502,  4503,  4504,  4508,  4509,  4510,  4513,  4547,
-    4573,  4597,  4600,  4616,  4619,  4636,  4639,  4645,  4648,  4655,
-    4658,  4665,  4721,  4791,  4796,  4863,  4899,  4907,  4950,  4989,
-    5009,  5041,  5068,  5094,  5120,  5146,  5172,  5194,  5222,  5250,
-    5278,  5306,  5334,  5373,  5412,  5433,  5454,  5481,  5485,  5495,
-    5530,  5531,  5532,  5536,  5542,  5554,  5572,  5600,  5601,  5602,
-    5603,  5604,  5605,  5606,  5607,  5608,  5615,  5616,  5617,  5618,
-    5619,  5620,  5621,  5622,  5623,  5624,  5625,  5626,  5627,  5628,
-    5629,  5630,  5631,  5632,  5633,  5634,  5635,  5636,  5637,  5638,
-    5639,  5640,  5641,  5642,  5643,  5644,  5645,  5646,  5647,  5656,
-    5657,  5658,  5659,  5660,  5661,  5662,  5663,  5664,  5665,  5666,
-    5671,  5670,  5678,  5683,  5688,  5705,  5723,  5741,  5759,  5777,
-    5782,  5788,  5803,  5822,  5842,  5862,  5882,  5905,  5910,  5915,
-    5925,  5935,  5940,  5951,  5960,  5965,  5970,  5997,  6001,  6005,
-    6009,  6013,  6020,  6024,  6028,  6032,  6039,  6044,  6051,  6056,
-    6060,  6065,  6069,  6077,  6088,  6092,  6104,  6112,  6120,  6127,
-    6137,  6166,  6170,  6174,  6178,  6182,  6186,  6190,  6194,  6198,
-    6227,  6256,  6285,  6314,  6327,  6340,  6353,  6366,  6376,  6386,
-    6396,  6408,  6421,  6433,  6437,  6441,  6445,  6449,  6467,  6485,
-    6493,  6501,  6530,  6543,  6548,  6552,  6556,  6568,  6572,  6584,
-    6601,  6611,  6615,  6630,  6635,  6642,  6646,  6659,  6673,  6687,
-    6701,  6715,  6723,  6734,  6738,  6742,  6750,  6756,  6762,  6770,
-    6778,  6785,  6793,  6808,  6822,  6836,  6848,  6864,  6873,  6882,
-    6892,  6903,  6911,  6919,  6923,  6942,  6949,  6955,  6962,  6970,
-    6969,  6982,  6987,  6993,  7002,  7015,  7018,  7022
+    3999,  4019,  4045,  4057,  4069,  4099,  4130,  4139,  4138,  4153,
+    4152,  4167,  4166,  4181,  4180,  4194,  4201,  4208,  4215,  4222,
+    4229,  4236,  4243,  4250,  4258,  4257,  4271,  4270,  4284,  4283,
+    4297,  4296,  4310,  4309,  4323,  4322,  4336,  4335,  4349,  4348,
+    4362,  4361,  4378,  4381,  4387,  4399,  4419,  4443,  4447,  4451,
+    4455,  4459,  4463,  4469,  4475,  4479,  4483,  4487,  4491,  4510,
+    4523,  4524,  4525,  4526,  4527,  4531,  4532,  4533,  4536,  4570,
+    4596,  4620,  4623,  4639,  4642,  4659,  4662,  4668,  4671,  4678,
+    4681,  4688,  4744,  4814,  4819,  4886,  4922,  4930,  4973,  5012,
+    5032,  5064,  5091,  5117,  5143,  5169,  5195,  5217,  5245,  5273,
+    5301,  5329,  5357,  5396,  5435,  5456,  5477,  5504,  5508,  5518,
+    5553,  5554,  5555,  5559,  5565,  5577,  5595,  5623,  5624,  5625,
+    5626,  5627,  5628,  5629,  5630,  5631,  5638,  5639,  5640,  5641,
+    5642,  5643,  5644,  5645,  5646,  5647,  5648,  5649,  5650,  5651,
+    5652,  5653,  5654,  5655,  5656,  5657,  5658,  5659,  5660,  5661,
+    5662,  5663,  5664,  5665,  5666,  5667,  5668,  5669,  5670,  5679,
+    5680,  5681,  5682,  5683,  5684,  5685,  5686,  5687,  5688,  5689,
+    5694,  5693,  5701,  5706,  5711,  5728,  5746,  5764,  5782,  5800,
+    5805,  5811,  5826,  5845,  5865,  5885,  5905,  5928,  5933,  5938,
+    5948,  5958,  5963,  5974,  5983,  5988,  5993,  6020,  6024,  6028,
+    6032,  6036,  6043,  6047,  6051,  6055,  6062,  6067,  6074,  6079,
+    6083,  6088,  6092,  6100,  6111,  6115,  6127,  6135,  6143,  6150,
+    6160,  6189,  6193,  6197,  6201,  6205,  6209,  6213,  6217,  6221,
+    6250,  6279,  6308,  6337,  6350,  6363,  6376,  6389,  6399,  6409,
+    6419,  6431,  6444,  6456,  6460,  6464,  6468,  6472,  6490,  6508,
+    6516,  6524,  6553,  6566,  6571,  6575,  6579,  6591,  6595,  6607,
+    6624,  6634,  6638,  6653,  6658,  6665,  6669,  6682,  6696,  6710,
+    6724,  6738,  6746,  6757,  6761,  6765,  6773,  6779,  6785,  6793,
+    6801,  6808,  6816,  6831,  6845,  6859,  6871,  6887,  6896,  6905,
+    6915,  6926,  6934,  6942,  6946,  6965,  6972,  6978,  6985,  6993,
+    6992,  7005,  7010,  7016,  7025,  7038,  7041,  7045
 };
 #endif
 
@@ -10325,15 +10325,38 @@ yyreduce:
 #line 4100 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
-      ExtrudeShapes(ROTATE, (yyvsp[(10) - (11)].l),
-		    0., 0., 0., (yyvsp[(3) - (11)].v)[0], (yyvsp[(3) - (11)].v)[1], (yyvsp[(3) - (11)].v)[2], (yyvsp[(5) - (11)].v)[0], (yyvsp[(5) - (11)].v)[1], (yyvsp[(5) - (11)].v)[2], (yyvsp[(7) - (11)].d),
-		    NULL, (yyval.l));
+      if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
+        std::vector<int> in[4], out[4];
+        Shape TheShape;
+        for(int i = 0; i < List_Nbr((yyvsp[(10) - (11)].l)); i++){
+          List_Read((yyvsp[(10) - (11)].l), i, &TheShape);
+          int dim = TheShape.Type / 100 - 1;
+          if(dim >= 0 && dim <= 3) in[dim].push_back(TheShape.Num);
+        }
+        GModel::current()->getOCCInternals()->revolve(-1, in, (yyvsp[(5) - (11)].v)[0], (yyvsp[(5) - (11)].v)[1], (yyvsp[(5) - (11)].v)[2],
+                                                      (yyvsp[(3) - (11)].v)[0], (yyvsp[(3) - (11)].v)[1], (yyvsp[(3) - (11)].v)[2], (yyvsp[(7) - (11)].d), out);
+        for(int dim = 0; dim < 4; dim++){
+          for(unsigned int i = 0; i < out[dim].size(); i++){
+            Shape s;
+            s.Num = out[dim][i];
+            s.Type = (dim == 3) ? MSH_VOLUME_FROM_GMODEL :
+              (dim == 2) ? MSH_SURF_FROM_GMODEL :
+              (dim == 1) ? MSH_SEGM_FROM_GMODEL : MSH_POINT_FROM_GMODEL;
+            List_Add((yyval.l), &s);
+          }
+        }
+      }
+      else{
+        ExtrudeShapes(ROTATE, (yyvsp[(10) - (11)].l),
+                      0., 0., 0., (yyvsp[(3) - (11)].v)[0], (yyvsp[(3) - (11)].v)[1], (yyvsp[(3) - (11)].v)[2], (yyvsp[(5) - (11)].v)[0], (yyvsp[(5) - (11)].v)[1], (yyvsp[(5) - (11)].v)[2], (yyvsp[(7) - (11)].d),
+                      NULL, (yyval.l));
+      }
       List_Delete((yyvsp[(10) - (11)].l));
     ;}
     break;
 
   case 286:
-#line 4108 "Gmsh.y"
+#line 4131 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE_ROTATE, (yyvsp[(12) - (13)].l),
@@ -10344,7 +10367,7 @@ yyreduce:
     break;
 
   case 287:
-#line 4116 "Gmsh.y"
+#line 4139 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10353,7 +10376,7 @@ yyreduce:
     break;
 
   case 288:
-#line 4122 "Gmsh.y"
+#line 4145 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE, (yyvsp[(4) - (7)].l),
@@ -10364,7 +10387,7 @@ yyreduce:
     break;
 
   case 289:
-#line 4130 "Gmsh.y"
+#line 4153 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10373,7 +10396,7 @@ yyreduce:
     break;
 
   case 290:
-#line 4136 "Gmsh.y"
+#line 4159 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(ROTATE, (yyvsp[(10) - (13)].l),
@@ -10384,7 +10407,7 @@ yyreduce:
     break;
 
   case 291:
-#line 4144 "Gmsh.y"
+#line 4167 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10393,7 +10416,7 @@ yyreduce:
     break;
 
   case 292:
-#line 4150 "Gmsh.y"
+#line 4173 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(TRANSLATE_ROTATE, (yyvsp[(12) - (15)].l),
@@ -10404,7 +10427,7 @@ yyreduce:
     break;
 
   case 293:
-#line 4158 "Gmsh.y"
+#line 4181 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10413,7 +10436,7 @@ yyreduce:
     break;
 
   case 294:
-#line 4164 "Gmsh.y"
+#line 4187 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShapes(BOUNDARY_LAYER, (yyvsp[(3) - (6)].l), 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
@@ -10423,7 +10446,7 @@ yyreduce:
     break;
 
   case 295:
-#line 4172 "Gmsh.y"
+#line 4195 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_POINT, (int)(yyvsp[(4) - (8)].d),
@@ -10433,7 +10456,7 @@ yyreduce:
     break;
 
   case 296:
-#line 4179 "Gmsh.y"
+#line 4202 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (8)].d),
@@ -10443,7 +10466,7 @@ yyreduce:
     break;
 
   case 297:
-#line 4186 "Gmsh.y"
+#line 4209 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (8)].d),
@@ -10453,7 +10476,7 @@ yyreduce:
     break;
 
   case 298:
-#line 4193 "Gmsh.y"
+#line 4216 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_POINT, (int)(yyvsp[(4) - (12)].d),
@@ -10463,7 +10486,7 @@ yyreduce:
     break;
 
   case 299:
-#line 4200 "Gmsh.y"
+#line 4223 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (12)].d),
@@ -10473,7 +10496,7 @@ yyreduce:
     break;
 
   case 300:
-#line 4207 "Gmsh.y"
+#line 4230 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (12)].d),
@@ -10483,7 +10506,7 @@ yyreduce:
     break;
 
   case 301:
-#line 4214 "Gmsh.y"
+#line 4237 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_POINT, (int)(yyvsp[(4) - (14)].d),
@@ -10493,7 +10516,7 @@ yyreduce:
     break;
 
   case 302:
-#line 4221 "Gmsh.y"
+#line 4244 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (14)].d),
@@ -10503,7 +10526,7 @@ yyreduce:
     break;
 
   case 303:
-#line 4228 "Gmsh.y"
+#line 4251 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (14)].d),
@@ -10513,7 +10536,7 @@ yyreduce:
     break;
 
   case 304:
-#line 4235 "Gmsh.y"
+#line 4258 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10522,7 +10545,7 @@ yyreduce:
     break;
 
   case 305:
-#line 4241 "Gmsh.y"
+#line 4264 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_POINT, (int)(yyvsp[(4) - (12)].d),
@@ -10532,7 +10555,7 @@ yyreduce:
     break;
 
   case 306:
-#line 4248 "Gmsh.y"
+#line 4271 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10541,7 +10564,7 @@ yyreduce:
     break;
 
   case 307:
-#line 4254 "Gmsh.y"
+#line 4277 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (12)].d),
@@ -10551,7 +10574,7 @@ yyreduce:
     break;
 
   case 308:
-#line 4261 "Gmsh.y"
+#line 4284 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10560,7 +10583,7 @@ yyreduce:
     break;
 
   case 309:
-#line 4267 "Gmsh.y"
+#line 4290 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (12)].d),
@@ -10570,7 +10593,7 @@ yyreduce:
     break;
 
   case 310:
-#line 4274 "Gmsh.y"
+#line 4297 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10579,7 +10602,7 @@ yyreduce:
     break;
 
   case 311:
-#line 4280 "Gmsh.y"
+#line 4303 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_POINT, (int)(yyvsp[(4) - (16)].d),
@@ -10589,7 +10612,7 @@ yyreduce:
     break;
 
   case 312:
-#line 4287 "Gmsh.y"
+#line 4310 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10598,7 +10621,7 @@ yyreduce:
     break;
 
   case 313:
-#line 4293 "Gmsh.y"
+#line 4316 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (16)].d),
@@ -10608,7 +10631,7 @@ yyreduce:
     break;
 
   case 314:
-#line 4300 "Gmsh.y"
+#line 4323 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10617,7 +10640,7 @@ yyreduce:
     break;
 
   case 315:
-#line 4306 "Gmsh.y"
+#line 4329 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (16)].d),
@@ -10627,7 +10650,7 @@ yyreduce:
     break;
 
   case 316:
-#line 4313 "Gmsh.y"
+#line 4336 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10636,7 +10659,7 @@ yyreduce:
     break;
 
   case 317:
-#line 4319 "Gmsh.y"
+#line 4342 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_POINT, (int)(yyvsp[(4) - (18)].d),
@@ -10646,7 +10669,7 @@ yyreduce:
     break;
 
   case 318:
-#line 4326 "Gmsh.y"
+#line 4349 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10655,7 +10678,7 @@ yyreduce:
     break;
 
   case 319:
-#line 4332 "Gmsh.y"
+#line 4355 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SEGM_LINE, (int)(yyvsp[(4) - (18)].d),
@@ -10665,7 +10688,7 @@ yyreduce:
     break;
 
   case 320:
-#line 4339 "Gmsh.y"
+#line 4362 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = extr.mesh.Recombine = false;
       extr.mesh.QuadToTri = NO_QUADTRI;
@@ -10674,7 +10697,7 @@ yyreduce:
     break;
 
   case 321:
-#line 4345 "Gmsh.y"
+#line 4368 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       ExtrudeShape(TRANSLATE_ROTATE, MSH_SURF_PLAN, (int)(yyvsp[(4) - (18)].d),
@@ -10684,19 +10707,19 @@ yyreduce:
     break;
 
   case 322:
-#line 4356 "Gmsh.y"
+#line 4379 "Gmsh.y"
     {
     ;}
     break;
 
   case 323:
-#line 4359 "Gmsh.y"
+#line 4382 "Gmsh.y"
     {
     ;}
     break;
 
   case 324:
-#line 4365 "Gmsh.y"
+#line 4388 "Gmsh.y"
     {
       int n = (int)fabs((yyvsp[(3) - (5)].d));
       if(n){ // we accept n==0 to easily disable layers
@@ -10711,7 +10734,7 @@ yyreduce:
     break;
 
   case 325:
-#line 4377 "Gmsh.y"
+#line 4400 "Gmsh.y"
     {
       extr.mesh.ExtrudeMesh = true;
       extr.mesh.NbLayer = List_Nbr((yyvsp[(3) - (7)].l));
@@ -10734,7 +10757,7 @@ yyreduce:
     break;
 
   case 326:
-#line 4397 "Gmsh.y"
+#line 4420 "Gmsh.y"
     {
       yymsg(0, "Explicit region numbers in layers are deprecated");
       extr.mesh.ExtrudeMesh = true;
@@ -10760,42 +10783,42 @@ yyreduce:
     break;
 
   case 327:
-#line 4421 "Gmsh.y"
+#line 4444 "Gmsh.y"
     {
       extr.mesh.ScaleLast = true;
     ;}
     break;
 
   case 328:
-#line 4425 "Gmsh.y"
+#line 4448 "Gmsh.y"
     {
       extr.mesh.Recombine = true;
     ;}
     break;
 
   case 329:
-#line 4429 "Gmsh.y"
+#line 4452 "Gmsh.y"
     {
       extr.mesh.Recombine = (yyvsp[(2) - (3)].d) ? true : false;
     ;}
     break;
 
   case 330:
-#line 4433 "Gmsh.y"
+#line 4456 "Gmsh.y"
     {
       yymsg(0, "Keyword 'QuadTriSngl' deprecated. Use 'QuadTriNoNewVerts' instead.");
     ;}
     break;
 
   case 331:
-#line 4437 "Gmsh.y"
+#line 4460 "Gmsh.y"
     {
       yymsg(0, "Keyword 'QuadTriSngl' deprecated. Use 'QuadTriNoNewVerts' instead.");
     ;}
     break;
 
   case 332:
-#line 4441 "Gmsh.y"
+#line 4464 "Gmsh.y"
     {
       yymsg(0, "Method 'QuadTriDbl' deprecated. Use 'QuadTriAddVerts' instead, "
             "which has no requirement for the number of extrusion layers and meshes "
@@ -10804,7 +10827,7 @@ yyreduce:
     break;
 
   case 333:
-#line 4447 "Gmsh.y"
+#line 4470 "Gmsh.y"
     {
       yymsg(0, "Method 'QuadTriDbl' deprecated. Use 'QuadTriAddVerts' instead, "
             "which has no requirement for the number of extrusion layers and meshes "
@@ -10813,35 +10836,35 @@ yyreduce:
     break;
 
   case 334:
-#line 4453 "Gmsh.y"
+#line 4476 "Gmsh.y"
     {
       extr.mesh.QuadToTri = QUADTRI_ADDVERTS_1;
     ;}
     break;
 
   case 335:
-#line 4457 "Gmsh.y"
+#line 4480 "Gmsh.y"
     {
       extr.mesh.QuadToTri = QUADTRI_ADDVERTS_1_RECOMB;
     ;}
     break;
 
   case 336:
-#line 4461 "Gmsh.y"
+#line 4484 "Gmsh.y"
     {
       extr.mesh.QuadToTri = QUADTRI_NOVERTS_1;
     ;}
     break;
 
   case 337:
-#line 4465 "Gmsh.y"
+#line 4488 "Gmsh.y"
     {
       extr.mesh.QuadToTri = QUADTRI_NOVERTS_1_RECOMB;
     ;}
     break;
 
   case 338:
-#line 4469 "Gmsh.y"
+#line 4492 "Gmsh.y"
     {
       int num = (int)(yyvsp[(3) - (9)].d);
       if(FindSurface(num)){
@@ -10863,7 +10886,7 @@ yyreduce:
     break;
 
   case 339:
-#line 4488 "Gmsh.y"
+#line 4511 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(2) - (6)].c), "Index"))
         extr.mesh.BoundaryLayerIndex = (yyvsp[(4) - (6)].d);
@@ -10874,47 +10897,47 @@ yyreduce:
     break;
 
   case 340:
-#line 4500 "Gmsh.y"
+#line 4523 "Gmsh.y"
     { (yyval.i) = OCC_Internals::Union; ;}
     break;
 
   case 341:
-#line 4501 "Gmsh.y"
+#line 4524 "Gmsh.y"
     { (yyval.i) = OCC_Internals::Intersection; ;}
     break;
 
   case 342:
-#line 4502 "Gmsh.y"
+#line 4525 "Gmsh.y"
     { (yyval.i) = OCC_Internals::Difference; ;}
     break;
 
   case 343:
-#line 4503 "Gmsh.y"
+#line 4526 "Gmsh.y"
     { (yyval.i) = OCC_Internals::Section; ;}
     break;
 
   case 344:
-#line 4504 "Gmsh.y"
+#line 4527 "Gmsh.y"
     { (yyval.i) = OCC_Internals::Fragments; ;}
     break;
 
   case 345:
-#line 4508 "Gmsh.y"
+#line 4531 "Gmsh.y"
     { (yyval.i) = 0; ;}
     break;
 
   case 346:
-#line 4509 "Gmsh.y"
+#line 4532 "Gmsh.y"
     { (yyval.i) = 1; ;}
     break;
 
   case 347:
-#line 4510 "Gmsh.y"
+#line 4533 "Gmsh.y"
     { (yyval.i) = (yyvsp[(2) - (3)].d); ;}
     break;
 
   case 348:
-#line 4515 "Gmsh.y"
+#line 4538 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
@@ -10950,7 +10973,7 @@ yyreduce:
     break;
 
   case 349:
-#line 4548 "Gmsh.y"
+#line 4571 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(Shape));
       if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
@@ -10976,7 +10999,7 @@ yyreduce:
     break;
 
   case 350:
-#line 4575 "Gmsh.y"
+#line 4598 "Gmsh.y"
     {
       if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
         std::vector<int> shape[4], tool[4];
@@ -10998,14 +11021,14 @@ yyreduce:
     break;
 
   case 351:
-#line 4597 "Gmsh.y"
+#line 4620 "Gmsh.y"
     {
       (yyval.v)[0] = (yyval.v)[1] = 1.;
     ;}
     break;
 
   case 352:
-#line 4601 "Gmsh.y"
+#line 4624 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(2) - (3)].c), "Progression") || !strcmp((yyvsp[(2) - (3)].c), "Power"))
         (yyval.v)[0] = 1.;
@@ -11021,14 +11044,14 @@ yyreduce:
     break;
 
   case 353:
-#line 4616 "Gmsh.y"
+#line 4639 "Gmsh.y"
     {
       (yyval.i) = -1; // left
     ;}
     break;
 
   case 354:
-#line 4620 "Gmsh.y"
+#line 4643 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (1)].c), "Right"))
         (yyval.i) = 1;
@@ -11045,49 +11068,49 @@ yyreduce:
     break;
 
   case 355:
-#line 4636 "Gmsh.y"
+#line 4659 "Gmsh.y"
     {
      (yyval.l) = List_Create(1, 1, sizeof(double));
    ;}
     break;
 
   case 356:
-#line 4640 "Gmsh.y"
+#line 4663 "Gmsh.y"
     {
      (yyval.l) = (yyvsp[(2) - (2)].l);
    ;}
     break;
 
   case 357:
-#line 4645 "Gmsh.y"
+#line 4668 "Gmsh.y"
     {
       (yyval.i) = 45;
     ;}
     break;
 
   case 358:
-#line 4649 "Gmsh.y"
+#line 4672 "Gmsh.y"
     {
       (yyval.i) = (int)(yyvsp[(2) - (2)].d);
     ;}
     break;
 
   case 359:
-#line 4655 "Gmsh.y"
+#line 4678 "Gmsh.y"
     {
       (yyval.l) = List_Create(1, 1, sizeof(double));
     ;}
     break;
 
   case 360:
-#line 4659 "Gmsh.y"
+#line 4682 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (2)].l);
     ;}
     break;
 
   case 361:
-#line 4666 "Gmsh.y"
+#line 4689 "Gmsh.y"
     {
       int type = (int)(yyvsp[(6) - (7)].v)[0];
       double coef = fabs((yyvsp[(6) - (7)].v)[1]);
@@ -11146,7 +11169,7 @@ yyreduce:
     break;
 
   case 362:
-#line 4722 "Gmsh.y"
+#line 4745 "Gmsh.y"
     {
       int k = List_Nbr((yyvsp[(4) - (6)].l));
       if(k != 0 && k != 3 && k != 4){
@@ -11219,7 +11242,7 @@ yyreduce:
     break;
 
   case 363:
-#line 4792 "Gmsh.y"
+#line 4815 "Gmsh.y"
     {
       yymsg(1, "Elliptic Surface is deprecated: use Transfinite instead (with smoothing)");
       List_Delete((yyvsp[(7) - (8)].l));
@@ -11227,7 +11250,7 @@ yyreduce:
     break;
 
   case 364:
-#line 4797 "Gmsh.y"
+#line 4820 "Gmsh.y"
     {
       int k = List_Nbr((yyvsp[(4) - (5)].l));
       if(k != 0 && k != 6 && k != 8){
@@ -11297,7 +11320,7 @@ yyreduce:
     break;
 
   case 365:
-#line 4864 "Gmsh.y"
+#line 4887 "Gmsh.y"
     {
       if(!(yyvsp[(2) - (3)].l)){
   	  List_T *tmp = Tree2List(GModel::current()->getGEOInternals()->Volumes);
@@ -11336,7 +11359,7 @@ yyreduce:
     break;
 
   case 366:
-#line 4900 "Gmsh.y"
+#line 4923 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (8)].l)); i++){
 	double d;
@@ -11347,7 +11370,7 @@ yyreduce:
     break;
 
   case 367:
-#line 4908 "Gmsh.y"
+#line 4931 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (5)].l)){
 	List_T *tmp = Tree2List(GModel::current()->getGEOInternals()->Surfaces);
@@ -11393,7 +11416,7 @@ yyreduce:
     break;
 
   case 368:
-#line 4951 "Gmsh.y"
+#line 4974 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (4)].l)){
 	List_T *tmp = Tree2List(GModel::current()->getGEOInternals()->Volumes);
@@ -11435,7 +11458,7 @@ yyreduce:
     break;
 
   case 369:
-#line 4990 "Gmsh.y"
+#line 5013 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (6)].l)); i++){
         double d;
@@ -11458,7 +11481,7 @@ yyreduce:
     break;
 
   case 370:
-#line 5011 "Gmsh.y"
+#line 5034 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (11)].l)) != List_Nbr((yyvsp[(8) - (11)].l))){
         yymsg(0, "Number of master lines (%d) different from number of "
@@ -11492,7 +11515,7 @@ yyreduce:
     break;
 
   case 371:
-#line 5043 "Gmsh.y"
+#line 5066 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (11)].l)) != List_Nbr((yyvsp[(8) - (11)].l))){
         yymsg(0, "Number of master faces (%d) different from number of "
@@ -11521,7 +11544,7 @@ yyreduce:
     break;
 
   case 372:
-#line 5070 "Gmsh.y"
+#line 5093 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (18)].l)) != List_Nbr((yyvsp[(8) - (18)].l))){
         yymsg(0, "Number of master edges (%d) different from number of "
@@ -11549,7 +11572,7 @@ yyreduce:
     break;
 
   case 373:
-#line 5096 "Gmsh.y"
+#line 5119 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (18)].l)) != List_Nbr((yyvsp[(8) - (18)].l))){
         yymsg(0, "Number of master faces (%d) different from number of "
@@ -11577,7 +11600,7 @@ yyreduce:
     break;
 
   case 374:
-#line 5122 "Gmsh.y"
+#line 5145 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (12)].l)) != List_Nbr((yyvsp[(8) - (12)].l))){
         yymsg(0, "Number of master edges (%d) different from number of "
@@ -11605,7 +11628,7 @@ yyreduce:
     break;
 
   case 375:
-#line 5148 "Gmsh.y"
+#line 5171 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(4) - (12)].l)) != List_Nbr((yyvsp[(8) - (12)].l))){
         yymsg(0, "Number of master faces (%d) different from number of "
@@ -11633,7 +11656,7 @@ yyreduce:
     break;
 
   case 376:
-#line 5174 "Gmsh.y"
+#line 5197 "Gmsh.y"
     {
       if (List_Nbr((yyvsp[(5) - (12)].l)) != List_Nbr((yyvsp[(10) - (12)].l))){
         yymsg(0, "Number of master surface edges (%d) different from number of "
@@ -11657,7 +11680,7 @@ yyreduce:
     break;
 
   case 377:
-#line 5195 "Gmsh.y"
+#line 5218 "Gmsh.y"
     {
       Surface *s = FindSurface((int)(yyvsp[(8) - (10)].d));
       if(s){
@@ -11688,7 +11711,7 @@ yyreduce:
     break;
 
   case 378:
-#line 5223 "Gmsh.y"
+#line 5246 "Gmsh.y"
     {
       Surface *s = FindSurface((int)(yyvsp[(8) - (10)].d));
       if(s){
@@ -11719,7 +11742,7 @@ yyreduce:
     break;
 
   case 379:
-#line 5251 "Gmsh.y"
+#line 5274 "Gmsh.y"
     {
       Volume *v = FindVolume((int)(yyvsp[(8) - (10)].d));
       if(v){
@@ -11750,7 +11773,7 @@ yyreduce:
     break;
 
   case 380:
-#line 5279 "Gmsh.y"
+#line 5302 "Gmsh.y"
     {
       Volume *v = FindVolume((int)(yyvsp[(8) - (10)].d));
       if(v){
@@ -11781,7 +11804,7 @@ yyreduce:
     break;
 
   case 381:
-#line 5307 "Gmsh.y"
+#line 5330 "Gmsh.y"
     {
       Volume *v = FindVolume((int)(yyvsp[(8) - (10)].d));
       if(v){
@@ -11812,7 +11835,7 @@ yyreduce:
     break;
 
   case 382:
-#line 5335 "Gmsh.y"
+#line 5358 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (4)].l)){
 	List_T *tmp = Tree2List(GModel::current()->getGEOInternals()->Surfaces);
@@ -11854,7 +11877,7 @@ yyreduce:
     break;
 
   case 383:
-#line 5374 "Gmsh.y"
+#line 5397 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (4)].l)){
 	List_T *tmp = Tree2List(GModel::current()->getGEOInternals()->Curves);
@@ -11896,7 +11919,7 @@ yyreduce:
     break;
 
   case 384:
-#line 5413 "Gmsh.y"
+#line 5436 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (4)].l)){
         for(GModel::viter it = GModel::current()->firstVertex();
@@ -11920,7 +11943,7 @@ yyreduce:
     break;
 
   case 385:
-#line 5434 "Gmsh.y"
+#line 5457 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (4)].l)){
         for(GModel::eiter it = GModel::current()->firstEdge();
@@ -11944,7 +11967,7 @@ yyreduce:
     break;
 
   case 386:
-#line 5455 "Gmsh.y"
+#line 5478 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (4)].l)){
         for(GModel::fiter it = GModel::current()->firstFace();
@@ -11968,14 +11991,14 @@ yyreduce:
     break;
 
   case 387:
-#line 5482 "Gmsh.y"
+#line 5505 "Gmsh.y"
     {
       ReplaceAllDuplicates();
     ;}
     break;
 
   case 388:
-#line 5486 "Gmsh.y"
+#line 5509 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(2) - (3)].c), "Geometry"))
         ReplaceAllDuplicates();
@@ -11988,7 +12011,7 @@ yyreduce:
     break;
 
   case 389:
-#line 5496 "Gmsh.y"
+#line 5519 "Gmsh.y"
     {
       if(List_Nbr((yyvsp[(4) - (6)].l)) >= 2){
         double d;
@@ -12021,22 +12044,22 @@ yyreduce:
     break;
 
   case 390:
-#line 5530 "Gmsh.y"
+#line 5553 "Gmsh.y"
     { (yyval.c) = (char*)"Homology"; ;}
     break;
 
   case 391:
-#line 5531 "Gmsh.y"
+#line 5554 "Gmsh.y"
     { (yyval.c) = (char*)"Cohomology"; ;}
     break;
 
   case 392:
-#line 5532 "Gmsh.y"
+#line 5555 "Gmsh.y"
     { (yyval.c) = (char*)"Betti"; ;}
     break;
 
   case 393:
-#line 5537 "Gmsh.y"
+#line 5560 "Gmsh.y"
     {
       std::vector<int> domain, subdomain, dim;
       for(int i = 0; i < 4; i++) dim.push_back(i);
@@ -12045,7 +12068,7 @@ yyreduce:
     break;
 
   case 394:
-#line 5543 "Gmsh.y"
+#line 5566 "Gmsh.y"
     {
       std::vector<int> domain, subdomain, dim;
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (5)].l)); i++){
@@ -12060,7 +12083,7 @@ yyreduce:
     break;
 
   case 395:
-#line 5555 "Gmsh.y"
+#line 5578 "Gmsh.y"
     {
       std::vector<int> domain, subdomain, dim;
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (7)].l)); i++){
@@ -12081,7 +12104,7 @@ yyreduce:
     break;
 
   case 396:
-#line 5573 "Gmsh.y"
+#line 5596 "Gmsh.y"
     {
       std::vector<int> domain, subdomain, dim;
       for(int i = 0; i < List_Nbr((yyvsp[(6) - (10)].l)); i++){
@@ -12107,47 +12130,47 @@ yyreduce:
     break;
 
   case 397:
-#line 5600 "Gmsh.y"
+#line 5623 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (1)].d);           ;}
     break;
 
   case 398:
-#line 5601 "Gmsh.y"
+#line 5624 "Gmsh.y"
     { (yyval.d) = (yyvsp[(2) - (3)].d);           ;}
     break;
 
   case 399:
-#line 5602 "Gmsh.y"
+#line 5625 "Gmsh.y"
     { (yyval.d) = -(yyvsp[(2) - (2)].d);          ;}
     break;
 
   case 400:
-#line 5603 "Gmsh.y"
+#line 5626 "Gmsh.y"
     { (yyval.d) = (yyvsp[(2) - (2)].d);           ;}
     break;
 
   case 401:
-#line 5604 "Gmsh.y"
+#line 5627 "Gmsh.y"
     { (yyval.d) = !(yyvsp[(2) - (2)].d);          ;}
     break;
 
   case 402:
-#line 5605 "Gmsh.y"
+#line 5628 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) - (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 403:
-#line 5606 "Gmsh.y"
+#line 5629 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) + (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 404:
-#line 5607 "Gmsh.y"
+#line 5630 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) * (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 405:
-#line 5609 "Gmsh.y"
+#line 5632 "Gmsh.y"
     {
       if(!(yyvsp[(3) - (3)].d))
 	yymsg(0, "Division by zero in '%g / %g'", (yyvsp[(1) - (3)].d), (yyvsp[(3) - (3)].d));
@@ -12157,232 +12180,232 @@ yyreduce:
     break;
 
   case 406:
-#line 5615 "Gmsh.y"
+#line 5638 "Gmsh.y"
     { (yyval.d) = (int)(yyvsp[(1) - (3)].d) % (int)(yyvsp[(3) - (3)].d);  ;}
     break;
 
   case 407:
-#line 5616 "Gmsh.y"
+#line 5639 "Gmsh.y"
     { (yyval.d) = pow((yyvsp[(1) - (3)].d), (yyvsp[(3) - (3)].d));  ;}
     break;
 
   case 408:
-#line 5617 "Gmsh.y"
+#line 5640 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) < (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 409:
-#line 5618 "Gmsh.y"
+#line 5641 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) > (yyvsp[(3) - (3)].d);      ;}
     break;
 
   case 410:
-#line 5619 "Gmsh.y"
+#line 5642 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) <= (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 411:
-#line 5620 "Gmsh.y"
+#line 5643 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) >= (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 412:
-#line 5621 "Gmsh.y"
+#line 5644 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) == (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 413:
-#line 5622 "Gmsh.y"
+#line 5645 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) != (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 414:
-#line 5623 "Gmsh.y"
+#line 5646 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) && (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 415:
-#line 5624 "Gmsh.y"
+#line 5647 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (3)].d) || (yyvsp[(3) - (3)].d);     ;}
     break;
 
   case 416:
-#line 5625 "Gmsh.y"
+#line 5648 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (5)].d) ? (yyvsp[(3) - (5)].d) : (yyvsp[(5) - (5)].d); ;}
     break;
 
   case 417:
-#line 5626 "Gmsh.y"
+#line 5649 "Gmsh.y"
     { (yyval.d) = exp((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 418:
-#line 5627 "Gmsh.y"
+#line 5650 "Gmsh.y"
     { (yyval.d) = log((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 419:
-#line 5628 "Gmsh.y"
+#line 5651 "Gmsh.y"
     { (yyval.d) = log10((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 420:
-#line 5629 "Gmsh.y"
+#line 5652 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 421:
-#line 5630 "Gmsh.y"
+#line 5653 "Gmsh.y"
     { (yyval.d) = sin((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 422:
-#line 5631 "Gmsh.y"
+#line 5654 "Gmsh.y"
     { (yyval.d) = asin((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 423:
-#line 5632 "Gmsh.y"
+#line 5655 "Gmsh.y"
     { (yyval.d) = cos((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 424:
-#line 5633 "Gmsh.y"
+#line 5656 "Gmsh.y"
     { (yyval.d) = acos((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 425:
-#line 5634 "Gmsh.y"
+#line 5657 "Gmsh.y"
     { (yyval.d) = tan((yyvsp[(3) - (4)].d));      ;}
     break;
 
   case 426:
-#line 5635 "Gmsh.y"
+#line 5658 "Gmsh.y"
     { (yyval.d) = atan((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 427:
-#line 5636 "Gmsh.y"
+#line 5659 "Gmsh.y"
     { (yyval.d) = atan2((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d));;}
     break;
 
   case 428:
-#line 5637 "Gmsh.y"
+#line 5660 "Gmsh.y"
     { (yyval.d) = sinh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 429:
-#line 5638 "Gmsh.y"
+#line 5661 "Gmsh.y"
     { (yyval.d) = cosh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 430:
-#line 5639 "Gmsh.y"
+#line 5662 "Gmsh.y"
     { (yyval.d) = tanh((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 431:
-#line 5640 "Gmsh.y"
+#line 5663 "Gmsh.y"
     { (yyval.d) = fabs((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 432:
-#line 5641 "Gmsh.y"
+#line 5664 "Gmsh.y"
     { (yyval.d) = floor((yyvsp[(3) - (4)].d));    ;}
     break;
 
   case 433:
-#line 5642 "Gmsh.y"
+#line 5665 "Gmsh.y"
     { (yyval.d) = ceil((yyvsp[(3) - (4)].d));     ;}
     break;
 
   case 434:
-#line 5643 "Gmsh.y"
+#line 5666 "Gmsh.y"
     { (yyval.d) = floor((yyvsp[(3) - (4)].d) + 0.5); ;}
     break;
 
   case 435:
-#line 5644 "Gmsh.y"
+#line 5667 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 436:
-#line 5645 "Gmsh.y"
+#line 5668 "Gmsh.y"
     { (yyval.d) = fmod((yyvsp[(3) - (6)].d), (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 437:
-#line 5646 "Gmsh.y"
+#line 5669 "Gmsh.y"
     { (yyval.d) = sqrt((yyvsp[(3) - (6)].d) * (yyvsp[(3) - (6)].d) + (yyvsp[(5) - (6)].d) * (yyvsp[(5) - (6)].d)); ;}
     break;
 
   case 438:
-#line 5647 "Gmsh.y"
+#line 5670 "Gmsh.y"
     { (yyval.d) = (yyvsp[(3) - (4)].d) * (double)rand() / (double)RAND_MAX; ;}
     break;
 
   case 439:
-#line 5656 "Gmsh.y"
+#line 5679 "Gmsh.y"
     { (yyval.d) = (yyvsp[(1) - (1)].d); ;}
     break;
 
   case 440:
-#line 5657 "Gmsh.y"
+#line 5680 "Gmsh.y"
     { (yyval.d) = 3.141592653589793; ;}
     break;
 
   case 441:
-#line 5658 "Gmsh.y"
+#line 5681 "Gmsh.y"
     { (yyval.d) = (double)ImbricatedTest; ;}
     break;
 
   case 442:
-#line 5659 "Gmsh.y"
+#line 5682 "Gmsh.y"
     { (yyval.d) = Msg::GetCommRank(); ;}
     break;
 
   case 443:
-#line 5660 "Gmsh.y"
+#line 5683 "Gmsh.y"
     { (yyval.d) = Msg::GetCommSize(); ;}
     break;
 
   case 444:
-#line 5661 "Gmsh.y"
+#line 5684 "Gmsh.y"
     { (yyval.d) = GetGmshMajorVersion(); ;}
     break;
 
   case 445:
-#line 5662 "Gmsh.y"
+#line 5685 "Gmsh.y"
     { (yyval.d) = GetGmshMinorVersion(); ;}
     break;
 
   case 446:
-#line 5663 "Gmsh.y"
+#line 5686 "Gmsh.y"
     { (yyval.d) = GetGmshPatchVersion(); ;}
     break;
 
   case 447:
-#line 5664 "Gmsh.y"
+#line 5687 "Gmsh.y"
     { (yyval.d) = Cpu(); ;}
     break;
 
   case 448:
-#line 5665 "Gmsh.y"
+#line 5688 "Gmsh.y"
     { (yyval.d) = GetMemoryUsage()/1024./1024.; ;}
     break;
 
   case 449:
-#line 5666 "Gmsh.y"
+#line 5689 "Gmsh.y"
     { (yyval.d) = TotalRam(); ;}
     break;
 
   case 450:
-#line 5671 "Gmsh.y"
+#line 5694 "Gmsh.y"
     { floatOptions.clear(); charOptions.clear(); ;}
     break;
 
   case 451:
-#line 5673 "Gmsh.y"
+#line 5696 "Gmsh.y"
     {
       std::vector<double> val(1, (yyvsp[(3) - (6)].d));
       Msg::ExchangeOnelabParameter("", val, floatOptions, charOptions);
@@ -12391,7 +12414,7 @@ yyreduce:
     break;
 
   case 452:
-#line 5679 "Gmsh.y"
+#line 5702 "Gmsh.y"
     {
       (yyval.d) = Msg::GetOnelabNumber((yyvsp[(3) - (4)].c));
       Free((yyvsp[(3) - (4)].c));
@@ -12399,7 +12422,7 @@ yyreduce:
     break;
 
   case 453:
-#line 5684 "Gmsh.y"
+#line 5707 "Gmsh.y"
     {
       (yyval.d) = Msg::GetOnelabNumber((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].d));
       Free((yyvsp[(3) - (6)].c));
@@ -12407,7 +12430,7 @@ yyreduce:
     break;
 
   case 454:
-#line 5689 "Gmsh.y"
+#line 5712 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(1) - (1)].c))){
 	yymsg(0, "Unknown variable '%s'", (yyvsp[(1) - (1)].c));
@@ -12427,7 +12450,7 @@ yyreduce:
     break;
 
   case 455:
-#line 5706 "Gmsh.y"
+#line 5729 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (4)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (4)].c))){
@@ -12448,7 +12471,7 @@ yyreduce:
     break;
 
   case 456:
-#line 5724 "Gmsh.y"
+#line 5747 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (4)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (4)].c))){
@@ -12469,7 +12492,7 @@ yyreduce:
     break;
 
   case 457:
-#line 5742 "Gmsh.y"
+#line 5765 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (4)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (4)].c))){
@@ -12490,7 +12513,7 @@ yyreduce:
     break;
 
   case 458:
-#line 5760 "Gmsh.y"
+#line 5783 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (4)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (4)].c))){
@@ -12511,7 +12534,7 @@ yyreduce:
     break;
 
   case 459:
-#line 5778 "Gmsh.y"
+#line 5801 "Gmsh.y"
     {
       (yyval.d) = gmsh_yysymbols.count((yyvsp[(3) - (4)].c));
       Free((yyvsp[(3) - (4)].c));
@@ -12519,7 +12542,7 @@ yyreduce:
     break;
 
   case 460:
-#line 5783 "Gmsh.y"
+#line 5806 "Gmsh.y"
     {
       std::string tmp = FixRelativePath(gmsh_yyname, (yyvsp[(3) - (4)].c));
       (yyval.d) = !StatFile(tmp);
@@ -12528,7 +12551,7 @@ yyreduce:
     break;
 
   case 461:
-#line 5789 "Gmsh.y"
+#line 5812 "Gmsh.y"
     {
       if(gmsh_yysymbols.count((yyvsp[(2) - (4)].c))){
         gmsh_yysymbol &s(gmsh_yysymbols[(yyvsp[(2) - (4)].c)]);
@@ -12546,7 +12569,7 @@ yyreduce:
     break;
 
   case 462:
-#line 5804 "Gmsh.y"
+#line 5827 "Gmsh.y"
     {
       if(!gmsh_yysymbols.count((yyvsp[(1) - (2)].c))){
 	yymsg(0, "Unknown variable '%s'", (yyvsp[(1) - (2)].c));
@@ -12568,7 +12591,7 @@ yyreduce:
     break;
 
   case 463:
-#line 5823 "Gmsh.y"
+#line 5846 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (5)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (5)].c))){
@@ -12591,7 +12614,7 @@ yyreduce:
     break;
 
   case 464:
-#line 5843 "Gmsh.y"
+#line 5866 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (5)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (5)].c))){
@@ -12614,7 +12637,7 @@ yyreduce:
     break;
 
   case 465:
-#line 5863 "Gmsh.y"
+#line 5886 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (5)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (5)].c))){
@@ -12637,7 +12660,7 @@ yyreduce:
     break;
 
   case 466:
-#line 5883 "Gmsh.y"
+#line 5906 "Gmsh.y"
     {
       int index = (int)(yyvsp[(3) - (5)].d);
       if(!gmsh_yysymbols.count((yyvsp[(1) - (5)].c))){
@@ -12660,7 +12683,7 @@ yyreduce:
     break;
 
   case 467:
-#line 5906 "Gmsh.y"
+#line 5929 "Gmsh.y"
     {
       NumberOption(GMSH_GET, (yyvsp[(1) - (3)].c), 0, (yyvsp[(3) - (3)].c), (yyval.d));
       Free((yyvsp[(1) - (3)].c)); Free((yyvsp[(3) - (3)].c));
@@ -12668,7 +12691,7 @@ yyreduce:
     break;
 
   case 468:
-#line 5911 "Gmsh.y"
+#line 5934 "Gmsh.y"
     {
       NumberOption(GMSH_GET, (yyvsp[(1) - (6)].c), (int)(yyvsp[(3) - (6)].d), (yyvsp[(6) - (6)].c), (yyval.d));
       Free((yyvsp[(1) - (6)].c)); Free((yyvsp[(6) - (6)].c));
@@ -12676,7 +12699,7 @@ yyreduce:
     break;
 
   case 469:
-#line 5916 "Gmsh.y"
+#line 5939 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (4)].c), 0, (yyvsp[(3) - (4)].c), d)){
@@ -12689,7 +12712,7 @@ yyreduce:
     break;
 
   case 470:
-#line 5926 "Gmsh.y"
+#line 5949 "Gmsh.y"
     {
       double d = 0.;
       if(NumberOption(GMSH_GET, (yyvsp[(1) - (7)].c), (int)(yyvsp[(3) - (7)].d), (yyvsp[(6) - (7)].c), d)){
@@ -12702,7 +12725,7 @@ yyreduce:
     break;
 
   case 471:
-#line 5936 "Gmsh.y"
+#line 5959 "Gmsh.y"
     {
       (yyval.d) = Msg::GetValue((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].d));
       Free((yyvsp[(3) - (6)].c));
@@ -12710,7 +12733,7 @@ yyreduce:
     break;
 
   case 472:
-#line 5941 "Gmsh.y"
+#line 5964 "Gmsh.y"
     {
       int matches = 0;
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (6)].l)); i++){
@@ -12724,7 +12747,7 @@ yyreduce:
     break;
 
   case 473:
-#line 5952 "Gmsh.y"
+#line 5975 "Gmsh.y"
     {
       std::string s((yyvsp[(3) - (6)].c)), substr((yyvsp[(5) - (6)].c));
       if(s.find(substr) != std::string::npos)
@@ -12736,7 +12759,7 @@ yyreduce:
     break;
 
   case 474:
-#line 5961 "Gmsh.y"
+#line 5984 "Gmsh.y"
     {
       (yyval.d) = strlen((yyvsp[(3) - (4)].c));
       Free((yyvsp[(3) - (4)].c));
@@ -12744,7 +12767,7 @@ yyreduce:
     break;
 
   case 475:
-#line 5966 "Gmsh.y"
+#line 5989 "Gmsh.y"
     {
       (yyval.d) = strcmp((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].c));
       Free((yyvsp[(3) - (6)].c)); Free((yyvsp[(5) - (6)].c));
@@ -12752,7 +12775,7 @@ yyreduce:
     break;
 
   case 476:
-#line 5971 "Gmsh.y"
+#line 5994 "Gmsh.y"
     {
       int align = 0, font = 0, fontsize = CTX::instance()->glFontSize;
       if(List_Nbr((yyvsp[(3) - (4)].l)) % 2){
@@ -12779,70 +12802,70 @@ yyreduce:
     break;
 
   case 477:
-#line 5998 "Gmsh.y"
+#line 6021 "Gmsh.y"
     {
       memcpy((yyval.v), (yyvsp[(1) - (1)].v), 5*sizeof(double));
     ;}
     break;
 
   case 478:
-#line 6002 "Gmsh.y"
+#line 6025 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = -(yyvsp[(2) - (2)].v)[i];
     ;}
     break;
 
   case 479:
-#line 6006 "Gmsh.y"
+#line 6029 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(2) - (2)].v)[i];
     ;}
     break;
 
   case 480:
-#line 6010 "Gmsh.y"
+#line 6033 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(1) - (3)].v)[i] - (yyvsp[(3) - (3)].v)[i];
     ;}
     break;
 
   case 481:
-#line 6014 "Gmsh.y"
+#line 6037 "Gmsh.y"
     {
       for(int i = 0; i < 5; i++) (yyval.v)[i] = (yyvsp[(1) - (3)].v)[i] + (yyvsp[(3) - (3)].v)[i];
     ;}
     break;
 
   case 482:
-#line 6021 "Gmsh.y"
+#line 6044 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (11)].d);  (yyval.v)[1] = (yyvsp[(4) - (11)].d);  (yyval.v)[2] = (yyvsp[(6) - (11)].d);  (yyval.v)[3] = (yyvsp[(8) - (11)].d); (yyval.v)[4] = (yyvsp[(10) - (11)].d);
     ;}
     break;
 
   case 483:
-#line 6025 "Gmsh.y"
+#line 6048 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (9)].d);  (yyval.v)[1] = (yyvsp[(4) - (9)].d);  (yyval.v)[2] = (yyvsp[(6) - (9)].d);  (yyval.v)[3] = (yyvsp[(8) - (9)].d); (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 484:
-#line 6029 "Gmsh.y"
+#line 6052 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (7)].d);  (yyval.v)[1] = (yyvsp[(4) - (7)].d);  (yyval.v)[2] = (yyvsp[(6) - (7)].d);  (yyval.v)[3] = 0.0; (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 485:
-#line 6033 "Gmsh.y"
+#line 6056 "Gmsh.y"
     {
       (yyval.v)[0] = (yyvsp[(2) - (7)].d);  (yyval.v)[1] = (yyvsp[(4) - (7)].d);  (yyval.v)[2] = (yyvsp[(6) - (7)].d);  (yyval.v)[3] = 0.0; (yyval.v)[4] = 1.0;
     ;}
     break;
 
   case 486:
-#line 6040 "Gmsh.y"
+#line 6063 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(List_T*));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].l)));
@@ -12850,14 +12873,14 @@ yyreduce:
     break;
 
   case 487:
-#line 6045 "Gmsh.y"
+#line 6068 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].l)));
     ;}
     break;
 
   case 488:
-#line 6052 "Gmsh.y"
+#line 6075 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].d)));
@@ -12865,14 +12888,14 @@ yyreduce:
     break;
 
   case 489:
-#line 6057 "Gmsh.y"
+#line 6080 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(1) - (1)].l);
     ;}
     break;
 
   case 490:
-#line 6061 "Gmsh.y"
+#line 6084 "Gmsh.y"
     {
       // creates an empty list
       (yyval.l) = List_Create(2, 1, sizeof(double));
@@ -12880,14 +12903,14 @@ yyreduce:
     break;
 
   case 491:
-#line 6066 "Gmsh.y"
+#line 6089 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (3)].l);
     ;}
     break;
 
   case 492:
-#line 6070 "Gmsh.y"
+#line 6093 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (4)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -12898,7 +12921,7 @@ yyreduce:
     break;
 
   case 493:
-#line 6078 "Gmsh.y"
+#line 6101 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(4) - (5)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -12909,14 +12932,14 @@ yyreduce:
     break;
 
   case 494:
-#line 6089 "Gmsh.y"
+#line 6112 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(1) - (1)].l);
     ;}
     break;
 
   case 495:
-#line 6093 "Gmsh.y"
+#line 6116 "Gmsh.y"
     {
       if(!strcmp((yyvsp[(1) - (1)].c), "*") || !strcmp((yyvsp[(1) - (1)].c), "all"))
         (yyval.l) = 0;
@@ -12928,7 +12951,7 @@ yyreduce:
     break;
 
   case 496:
-#line 6105 "Gmsh.y"
+#line 6128 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (2)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -12939,7 +12962,7 @@ yyreduce:
     break;
 
   case 497:
-#line 6113 "Gmsh.y"
+#line 6136 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (3)].l);
       for(int i = 0; i < List_Nbr((yyval.l)); i++){
@@ -12950,7 +12973,7 @@ yyreduce:
     break;
 
   case 498:
-#line 6121 "Gmsh.y"
+#line 6144 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       for(double d = (yyvsp[(1) - (3)].d); ((yyvsp[(1) - (3)].d) < (yyvsp[(3) - (3)].d)) ? (d <= (yyvsp[(3) - (3)].d)) : (d >= (yyvsp[(3) - (3)].d));
@@ -12960,7 +12983,7 @@ yyreduce:
     break;
 
   case 499:
-#line 6128 "Gmsh.y"
+#line 6151 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!(yyvsp[(5) - (5)].d)){  //|| ($1 < $3 && $5 < 0) || ($1 > $3 && $5 > 0)
@@ -12973,7 +12996,7 @@ yyreduce:
     break;
 
   case 500:
-#line 6138 "Gmsh.y"
+#line 6161 "Gmsh.y"
     {
       // Returns the coordinates of a point and fills a list with it.
       // This allows to ensure e.g. that relative point positions are
@@ -13005,63 +13028,63 @@ yyreduce:
     break;
 
   case 501:
-#line 6167 "Gmsh.y"
+#line 6190 "Gmsh.y"
     {
       (yyval.l) = GetAllElementaryEntityNumbers(0);
     ;}
     break;
 
   case 502:
-#line 6171 "Gmsh.y"
+#line 6194 "Gmsh.y"
     {
       (yyval.l) = GetAllElementaryEntityNumbers(1);
     ;}
     break;
 
   case 503:
-#line 6175 "Gmsh.y"
+#line 6198 "Gmsh.y"
     {
       (yyval.l) = GetAllElementaryEntityNumbers(2);
     ;}
     break;
 
   case 504:
-#line 6179 "Gmsh.y"
+#line 6202 "Gmsh.y"
     {
       (yyval.l) = GetAllElementaryEntityNumbers(3);
     ;}
     break;
 
   case 505:
-#line 6183 "Gmsh.y"
+#line 6206 "Gmsh.y"
     {
       (yyval.l) = GetAllPhysicalEntityNumbers(0);
     ;}
     break;
 
   case 506:
-#line 6187 "Gmsh.y"
+#line 6210 "Gmsh.y"
     {
       (yyval.l) = GetAllPhysicalEntityNumbers(1);
     ;}
     break;
 
   case 507:
-#line 6191 "Gmsh.y"
+#line 6214 "Gmsh.y"
     {
       (yyval.l) = GetAllPhysicalEntityNumbers(2);
     ;}
     break;
 
   case 508:
-#line 6195 "Gmsh.y"
+#line 6218 "Gmsh.y"
     {
       (yyval.l) = GetAllPhysicalEntityNumbers(3);
     ;}
     break;
 
   case 509:
-#line 6199 "Gmsh.y"
+#line 6222 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (5)].l)); i++){
@@ -13093,7 +13116,7 @@ yyreduce:
     break;
 
   case 510:
-#line 6228 "Gmsh.y"
+#line 6251 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (5)].l)); i++){
@@ -13125,7 +13148,7 @@ yyreduce:
     break;
 
   case 511:
-#line 6257 "Gmsh.y"
+#line 6280 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (5)].l)); i++){
@@ -13157,7 +13180,7 @@ yyreduce:
     break;
 
   case 512:
-#line 6286 "Gmsh.y"
+#line 6309 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(4) - (5)].l)); i++){
@@ -13189,7 +13212,7 @@ yyreduce:
     break;
 
   case 513:
-#line 6316 "Gmsh.y"
+#line 6339 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 1, sizeof(double));
       GModel::current()->importGEOInternals();
@@ -13204,7 +13227,7 @@ yyreduce:
     break;
 
   case 514:
-#line 6329 "Gmsh.y"
+#line 6352 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 1, sizeof(double));
       GModel::current()->importGEOInternals();
@@ -13219,7 +13242,7 @@ yyreduce:
     break;
 
   case 515:
-#line 6342 "Gmsh.y"
+#line 6365 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 1, sizeof(double));
       GModel::current()->importGEOInternals();
@@ -13234,7 +13257,7 @@ yyreduce:
     break;
 
   case 516:
-#line 6355 "Gmsh.y"
+#line 6378 "Gmsh.y"
     {
       (yyval.l) = List_Create(10, 1, sizeof(double));
       GModel::current()->importGEOInternals();
@@ -13249,7 +13272,7 @@ yyreduce:
     break;
 
   case 517:
-#line 6367 "Gmsh.y"
+#line 6390 "Gmsh.y"
     {
       (yyval.l) = List_Create(List_Nbr((yyvsp[(1) - (1)].l)), 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(1) - (1)].l)); i++){
@@ -13262,7 +13285,7 @@ yyreduce:
     break;
 
   case 518:
-#line 6377 "Gmsh.y"
+#line 6400 "Gmsh.y"
     {
       (yyval.l) = List_Create(List_Nbr((yyvsp[(1) - (1)].l)), 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(1) - (1)].l)); i++){
@@ -13275,7 +13298,7 @@ yyreduce:
     break;
 
   case 519:
-#line 6387 "Gmsh.y"
+#line 6410 "Gmsh.y"
     {
       (yyval.l) = List_Create(List_Nbr((yyvsp[(1) - (1)].l)), 1, sizeof(double));
       for(int i = 0; i < List_Nbr((yyvsp[(1) - (1)].l)); i++){
@@ -13288,7 +13311,7 @@ yyreduce:
     break;
 
   case 520:
-#line 6397 "Gmsh.y"
+#line 6420 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(1) - (3)].c)))
@@ -13303,7 +13326,7 @@ yyreduce:
     break;
 
   case 521:
-#line 6409 "Gmsh.y"
+#line 6432 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(1) - (3)].c)))
@@ -13318,7 +13341,7 @@ yyreduce:
     break;
 
   case 522:
-#line 6422 "Gmsh.y"
+#line 6445 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(3) - (4)].c)))
@@ -13333,35 +13356,35 @@ yyreduce:
     break;
 
   case 523:
-#line 6434 "Gmsh.y"
+#line 6457 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (4)].l);
     ;}
     break;
 
   case 524:
-#line 6438 "Gmsh.y"
+#line 6461 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(3) - (4)].l);
     ;}
     break;
 
   case 525:
-#line 6442 "Gmsh.y"
+#line 6465 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(4) - (6)].l);
     ;}
     break;
 
   case 526:
-#line 6446 "Gmsh.y"
+#line 6469 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(4) - (6)].l);
     ;}
     break;
 
   case 527:
-#line 6450 "Gmsh.y"
+#line 6473 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(1) - (6)].c)))
@@ -13382,7 +13405,7 @@ yyreduce:
     break;
 
   case 528:
-#line 6468 "Gmsh.y"
+#line 6491 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       if(!gmsh_yysymbols.count((yyvsp[(1) - (6)].c)))
@@ -13403,7 +13426,7 @@ yyreduce:
     break;
 
   case 529:
-#line 6486 "Gmsh.y"
+#line 6509 "Gmsh.y"
     {
       (yyval.l) = List_Create(20,20,sizeof(double));
       for(int i = 0; i < (int)(yyvsp[(7) - (8)].d); i++) {
@@ -13414,7 +13437,7 @@ yyreduce:
     break;
 
   case 530:
-#line 6494 "Gmsh.y"
+#line 6517 "Gmsh.y"
     {
       (yyval.l) = List_Create(20,20,sizeof(double));
       for(int i = 0; i < (int)(yyvsp[(7) - (8)].d); i++) {
@@ -13425,7 +13448,7 @@ yyreduce:
     break;
 
   case 531:
-#line 6502 "Gmsh.y"
+#line 6525 "Gmsh.y"
     {
       Msg::Barrier();
       FILE *File;
@@ -13457,7 +13480,7 @@ yyreduce:
     break;
 
   case 532:
-#line 6531 "Gmsh.y"
+#line 6554 "Gmsh.y"
     {
       double x0 = (yyvsp[(3) - (14)].d), x1 = (yyvsp[(5) - (14)].d), y0 = (yyvsp[(7) - (14)].d), y1 = (yyvsp[(9) - (14)].d), ys = (yyvsp[(11) - (14)].d);
       int N = (int)(yyvsp[(13) - (14)].d);
@@ -13470,7 +13493,7 @@ yyreduce:
     break;
 
   case 533:
-#line 6544 "Gmsh.y"
+#line 6567 "Gmsh.y"
     {
       (yyval.l) = List_Create(2, 1, sizeof(double));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].d)));
@@ -13478,21 +13501,21 @@ yyreduce:
     break;
 
   case 534:
-#line 6549 "Gmsh.y"
+#line 6572 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(1) - (1)].l);
     ;}
     break;
 
   case 535:
-#line 6553 "Gmsh.y"
+#line 6576 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].d)));
     ;}
     break;
 
   case 536:
-#line 6557 "Gmsh.y"
+#line 6580 "Gmsh.y"
     {
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (3)].l)); i++){
 	double d;
@@ -13504,21 +13527,21 @@ yyreduce:
     break;
 
   case 537:
-#line 6569 "Gmsh.y"
+#line 6592 "Gmsh.y"
     {
       (yyval.u) = CTX::instance()->packColor((int)(yyvsp[(2) - (9)].d), (int)(yyvsp[(4) - (9)].d), (int)(yyvsp[(6) - (9)].d), (int)(yyvsp[(8) - (9)].d));
     ;}
     break;
 
   case 538:
-#line 6573 "Gmsh.y"
+#line 6596 "Gmsh.y"
     {
       (yyval.u) = CTX::instance()->packColor((int)(yyvsp[(2) - (7)].d), (int)(yyvsp[(4) - (7)].d), (int)(yyvsp[(6) - (7)].d), 255);
     ;}
     break;
 
   case 539:
-#line 6585 "Gmsh.y"
+#line 6608 "Gmsh.y"
     {
       int flag = 0;
       if(gmsh_yystringsymbols.count((yyvsp[(1) - (1)].c))){
@@ -13538,7 +13561,7 @@ yyreduce:
     break;
 
   case 540:
-#line 6602 "Gmsh.y"
+#line 6625 "Gmsh.y"
     {
       unsigned int val = 0;
       ColorOption(GMSH_GET, (yyvsp[(1) - (5)].c), 0, (yyvsp[(5) - (5)].c), val);
@@ -13548,14 +13571,14 @@ yyreduce:
     break;
 
   case 541:
-#line 6612 "Gmsh.y"
+#line 6635 "Gmsh.y"
     {
       (yyval.l) = (yyvsp[(2) - (3)].l);
     ;}
     break;
 
   case 542:
-#line 6616 "Gmsh.y"
+#line 6639 "Gmsh.y"
     {
       (yyval.l) = List_Create(256, 10, sizeof(unsigned int));
       GmshColorTable *ct = GetColorTable((int)(yyvsp[(3) - (6)].d));
@@ -13570,7 +13593,7 @@ yyreduce:
     break;
 
   case 543:
-#line 6631 "Gmsh.y"
+#line 6654 "Gmsh.y"
     {
       (yyval.l) = List_Create(256, 10, sizeof(unsigned int));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].u)));
@@ -13578,21 +13601,21 @@ yyreduce:
     break;
 
   case 544:
-#line 6636 "Gmsh.y"
+#line 6659 "Gmsh.y"
     {
       List_Add((yyval.l), &((yyvsp[(3) - (3)].u)));
     ;}
     break;
 
   case 545:
-#line 6643 "Gmsh.y"
+#line 6666 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(1) - (1)].c);
     ;}
     break;
 
   case 546:
-#line 6647 "Gmsh.y"
+#line 6670 "Gmsh.y"
     {
       std::string val;
       if(!gmsh_yystringsymbols.count((yyvsp[(1) - (1)].c)))
@@ -13608,7 +13631,7 @@ yyreduce:
     break;
 
   case 547:
-#line 6660 "Gmsh.y"
+#line 6683 "Gmsh.y"
     {
       std::string val;
       int j = (int)(yyvsp[(3) - (4)].d);
@@ -13625,7 +13648,7 @@ yyreduce:
     break;
 
   case 548:
-#line 6674 "Gmsh.y"
+#line 6697 "Gmsh.y"
     {
       std::string val;
       int j = (int)(yyvsp[(3) - (4)].d);
@@ -13642,7 +13665,7 @@ yyreduce:
     break;
 
   case 549:
-#line 6688 "Gmsh.y"
+#line 6711 "Gmsh.y"
     {
       std::string val;
       int j = (int)(yyvsp[(3) - (4)].d);
@@ -13659,7 +13682,7 @@ yyreduce:
     break;
 
   case 550:
-#line 6702 "Gmsh.y"
+#line 6725 "Gmsh.y"
     {
       std::string val;
       int j = (int)(yyvsp[(3) - (4)].d);
@@ -13676,7 +13699,7 @@ yyreduce:
     break;
 
   case 551:
-#line 6716 "Gmsh.y"
+#line 6739 "Gmsh.y"
     {
       std::string out;
       StringOption(GMSH_GET, (yyvsp[(1) - (3)].c), 0, (yyvsp[(3) - (3)].c), out);
@@ -13687,7 +13710,7 @@ yyreduce:
     break;
 
   case 552:
-#line 6724 "Gmsh.y"
+#line 6747 "Gmsh.y"
     {
       std::string out;
       StringOption(GMSH_GET, (yyvsp[(1) - (6)].c), (int)(yyvsp[(3) - (6)].d), (yyvsp[(6) - (6)].c), out);
@@ -13698,21 +13721,21 @@ yyreduce:
     break;
 
   case 553:
-#line 6735 "Gmsh.y"
+#line 6758 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(1) - (1)].c);
     ;}
     break;
 
   case 554:
-#line 6739 "Gmsh.y"
+#line 6762 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(3) - (4)].c);
     ;}
     break;
 
   case 555:
-#line 6743 "Gmsh.y"
+#line 6766 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc(32 * sizeof(char));
       time_t now;
@@ -13723,7 +13746,7 @@ yyreduce:
     break;
 
   case 556:
-#line 6751 "Gmsh.y"
+#line 6774 "Gmsh.y"
     {
       std::string exe = Msg::GetExecutableName();
       (yyval.c) = (char *)Malloc(exe.size() + 1);
@@ -13732,7 +13755,7 @@ yyreduce:
     break;
 
   case 557:
-#line 6757 "Gmsh.y"
+#line 6780 "Gmsh.y"
     {
       std::string action = Msg::GetOnelabAction();
       (yyval.c) = (char *)Malloc(action.size() + 1);
@@ -13741,7 +13764,7 @@ yyreduce:
     break;
 
   case 558:
-#line 6763 "Gmsh.y"
+#line 6786 "Gmsh.y"
     {
       const char *env = GetEnvironmentVar((yyvsp[(3) - (4)].c));
       if(!env) env = "";
@@ -13752,7 +13775,7 @@ yyreduce:
     break;
 
   case 559:
-#line 6771 "Gmsh.y"
+#line 6794 "Gmsh.y"
     {
       std::string s = Msg::GetString((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].c));
       (yyval.c) = (char *)Malloc((s.size() + 1) * sizeof(char));
@@ -13763,7 +13786,7 @@ yyreduce:
     break;
 
   case 560:
-#line 6779 "Gmsh.y"
+#line 6802 "Gmsh.y"
     {
       std::string s = Msg::GetOnelabString((yyvsp[(3) - (4)].c));
       (yyval.c) = (char *)Malloc((s.size() + 1) * sizeof(char));
@@ -13773,7 +13796,7 @@ yyreduce:
     break;
 
   case 561:
-#line 6786 "Gmsh.y"
+#line 6809 "Gmsh.y"
     {
       std::string s = Msg::GetOnelabString((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].c));
       (yyval.c) = (char *)Malloc((s.size() + 1) * sizeof(char));
@@ -13784,7 +13807,7 @@ yyreduce:
     break;
 
   case 562:
-#line 6794 "Gmsh.y"
+#line 6817 "Gmsh.y"
     {
       int size = 1;
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++)
@@ -13802,7 +13825,7 @@ yyreduce:
     break;
 
   case 563:
-#line 6809 "Gmsh.y"
+#line 6832 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc((strlen((yyvsp[(3) - (4)].c)) + 1) * sizeof(char));
       int i;
@@ -13819,7 +13842,7 @@ yyreduce:
     break;
 
   case 564:
-#line 6823 "Gmsh.y"
+#line 6846 "Gmsh.y"
     {
       (yyval.c) = (char *)Malloc((strlen((yyvsp[(3) - (4)].c)) + 1) * sizeof(char));
       int i;
@@ -13836,7 +13859,7 @@ yyreduce:
     break;
 
   case 565:
-#line 6837 "Gmsh.y"
+#line 6860 "Gmsh.y"
     {
       std::string input = (yyvsp[(3) - (8)].c);
       std::string substr_old = (yyvsp[(5) - (8)].c);
@@ -13851,7 +13874,7 @@ yyreduce:
     break;
 
   case 566:
-#line 6849 "Gmsh.y"
+#line 6872 "Gmsh.y"
     {
       int size = 1;
       for(int i = 0; i < List_Nbr((yyvsp[(3) - (4)].l)); i++)
@@ -13870,7 +13893,7 @@ yyreduce:
     break;
 
   case 567:
-#line 6865 "Gmsh.y"
+#line 6888 "Gmsh.y"
     {
       int i = 0;
       while ((yyvsp[(3) - (4)].c)[i]) {
@@ -13882,7 +13905,7 @@ yyreduce:
     break;
 
   case 568:
-#line 6874 "Gmsh.y"
+#line 6897 "Gmsh.y"
     {
       int i = 0;
       while ((yyvsp[(3) - (4)].c)[i]) {
@@ -13894,7 +13917,7 @@ yyreduce:
     break;
 
   case 569:
-#line 6883 "Gmsh.y"
+#line 6906 "Gmsh.y"
     {
       int i = 0;
       while ((yyvsp[(3) - (4)].c)[i]) {
@@ -13907,7 +13930,7 @@ yyreduce:
     break;
 
   case 570:
-#line 6893 "Gmsh.y"
+#line 6916 "Gmsh.y"
     {
       if((yyvsp[(3) - (8)].d)){
         (yyval.c) = (yyvsp[(5) - (8)].c);
@@ -13921,7 +13944,7 @@ yyreduce:
     break;
 
   case 571:
-#line 6904 "Gmsh.y"
+#line 6927 "Gmsh.y"
     {
       std::string in = (yyvsp[(3) - (8)].c);
       std::string out = in.substr((int)(yyvsp[(5) - (8)].d), (int)(yyvsp[(7) - (8)].d));
@@ -13932,7 +13955,7 @@ yyreduce:
     break;
 
   case 572:
-#line 6912 "Gmsh.y"
+#line 6935 "Gmsh.y"
     {
       std::string in = (yyvsp[(3) - (6)].c);
       std::string out = in.substr((int)(yyvsp[(5) - (6)].d), std::string::npos);
@@ -13943,14 +13966,14 @@ yyreduce:
     break;
 
   case 573:
-#line 6920 "Gmsh.y"
+#line 6943 "Gmsh.y"
     {
       (yyval.c) = (yyvsp[(3) - (4)].c);
     ;}
     break;
 
   case 574:
-#line 6924 "Gmsh.y"
+#line 6947 "Gmsh.y"
     {
       char tmpstring[5000];
       int i = PrintListOfDouble((yyvsp[(3) - (6)].c), (yyvsp[(5) - (6)].l), tmpstring);
@@ -13972,7 +13995,7 @@ yyreduce:
     break;
 
   case 575:
-#line 6943 "Gmsh.y"
+#line 6966 "Gmsh.y"
     {
       std::string tmp = FixRelativePath(gmsh_yyname, (yyvsp[(3) - (4)].c));
       (yyval.c) = (char*)Malloc((tmp.size() + 1) * sizeof(char));
@@ -13982,7 +14005,7 @@ yyreduce:
     break;
 
   case 576:
-#line 6950 "Gmsh.y"
+#line 6973 "Gmsh.y"
     {
       std::string tmp = SplitFileName(GetAbsolutePath(gmsh_yyname))[0];
       (yyval.c) = (char*)Malloc((tmp.size() + 1) * sizeof(char));
@@ -13991,7 +14014,7 @@ yyreduce:
     break;
 
   case 577:
-#line 6956 "Gmsh.y"
+#line 6979 "Gmsh.y"
     {
       std::string tmp = SplitFileName((yyvsp[(3) - (4)].c))[0];
       (yyval.c) = (char*)Malloc((tmp.size() + 1) * sizeof(char));
@@ -14001,7 +14024,7 @@ yyreduce:
     break;
 
   case 578:
-#line 6963 "Gmsh.y"
+#line 6986 "Gmsh.y"
     {
       std::string tmp = GetAbsolutePath((yyvsp[(3) - (4)].c));
       (yyval.c) = (char*)Malloc((tmp.size() + 1) * sizeof(char));
@@ -14011,12 +14034,12 @@ yyreduce:
     break;
 
   case 579:
-#line 6970 "Gmsh.y"
+#line 6993 "Gmsh.y"
     { floatOptions.clear(); charOptions.clear(); ;}
     break;
 
   case 580:
-#line 6972 "Gmsh.y"
+#line 6995 "Gmsh.y"
     {
       std::string val((yyvsp[(3) - (6)].c));
       Msg::ExchangeOnelabParameter("", val, floatOptions, charOptions);
@@ -14027,7 +14050,7 @@ yyreduce:
     break;
 
   case 581:
-#line 6983 "Gmsh.y"
+#line 7006 "Gmsh.y"
     {
       (yyval.l) = List_Create(20,20,sizeof(char*));
       List_Add((yyval.l), &((yyvsp[(1) - (1)].c)));
@@ -14035,12 +14058,12 @@ yyreduce:
     break;
 
   case 582:
-#line 6988 "Gmsh.y"
+#line 7011 "Gmsh.y"
     { List_Add((yyval.l), &((yyvsp[(3) - (3)].c))); ;}
     break;
 
   case 583:
-#line 6994 "Gmsh.y"
+#line 7017 "Gmsh.y"
     {
       char tmpstr[256];
       sprintf(tmpstr, "_%d", (int)(yyvsp[(4) - (5)].d));
@@ -14051,7 +14074,7 @@ yyreduce:
     break;
 
   case 584:
-#line 7003 "Gmsh.y"
+#line 7026 "Gmsh.y"
     {
       char tmpstr[256];
       sprintf(tmpstr, "_%d", (int)(yyvsp[(4) - (5)].d));
@@ -14062,23 +14085,23 @@ yyreduce:
     break;
 
   case 585:
-#line 7016 "Gmsh.y"
+#line 7039 "Gmsh.y"
     { (yyval.c) = (yyvsp[(1) - (1)].c); ;}
     break;
 
   case 586:
-#line 7019 "Gmsh.y"
+#line 7042 "Gmsh.y"
     { (yyval.c) = (yyvsp[(1) - (1)].c); ;}
     break;
 
   case 587:
-#line 7023 "Gmsh.y"
+#line 7046 "Gmsh.y"
     { (yyval.c) = (yyvsp[(3) - (4)].c); ;}
     break;
 
 
 /* Line 1267 of yacc.c.  */
-#line 14082 "Gmsh.tab.cpp"
+#line 14105 "Gmsh.tab.cpp"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -14292,7 +14315,7 @@ yyreturn:
 }
 
 
-#line 7026 "Gmsh.y"
+#line 7049 "Gmsh.y"
 
 
 void assignVariable(const std::string &name, int index, int assignType,
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index aada971c0febad6e013f7332c49c6828b2c9f318..66427befcfd8c353f78369769ddb3a8e6c611581 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -4099,9 +4099,32 @@ Extrude :
   | tExtrude '{' VExpr ',' VExpr ',' FExpr '}' '{' ListOfShapes '}'
     {
       $$ = List_Create(2, 1, sizeof(Shape));
-      ExtrudeShapes(ROTATE, $10,
-		    0., 0., 0., $3[0], $3[1], $3[2], $5[0], $5[1], $5[2], $7,
-		    NULL, $$);
+      if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
+        std::vector<int> in[4], out[4];
+        Shape TheShape;
+        for(int i = 0; i < List_Nbr($10); i++){
+          List_Read($10, i, &TheShape);
+          int dim = TheShape.Type / 100 - 1;
+          if(dim >= 0 && dim <= 3) in[dim].push_back(TheShape.Num);
+        }
+        GModel::current()->getOCCInternals()->revolve(-1, in, $5[0], $5[1], $5[2],
+                                                      $3[0], $3[1], $3[2], $7, out);
+        for(int dim = 0; dim < 4; dim++){
+          for(unsigned int i = 0; i < out[dim].size(); i++){
+            Shape s;
+            s.Num = out[dim][i];
+            s.Type = (dim == 3) ? MSH_VOLUME_FROM_GMODEL :
+              (dim == 2) ? MSH_SURF_FROM_GMODEL :
+              (dim == 1) ? MSH_SEGM_FROM_GMODEL : MSH_POINT_FROM_GMODEL;
+            List_Add($$, &s);
+          }
+        }
+      }
+      else{
+        ExtrudeShapes(ROTATE, $10,
+                      0., 0., 0., $3[0], $3[1], $3[2], $5[0], $5[1], $5[2], $7,
+                      NULL, $$);
+      }
       List_Delete($10);
     }
   | tExtrude '{' VExpr ',' VExpr ',' VExpr ',' FExpr '}' '{' ListOfShapes '}'
diff --git a/demos/boolean/extrude.geo b/demos/boolean/extrude.geo
index 420a71ea551df0e400e5761a7165a8a7a0de0b1f..a818edd66efebe1cdca2e3049bb8e6014075f486 100644
--- a/demos/boolean/extrude.geo
+++ b/demos/boolean/extrude.geo
@@ -28,6 +28,15 @@ Plane Surface(2) = {2};
 
 Disk(3) = {0.6, 0.6, 0, 0.5, 0.3};
 
-Extrude{0,0,0.3}{ Surface{1:3}; }
-BooleanFragments{ Volume{1}; Delete; }{ Volume{2:3}; Delete; }
-Delete{ Surface{1:3}; }
+DefineConstant[
+  after = {1, Choices{0,1}, Name "Parameters/Extrude after boolean"}
+];
+
+If(after)
+  BooleanFragments{ Surface{1}; Delete; }{ Surface{2:3}; Delete; }
+  Extrude{0,0,0.3}{ Surface{1:5}; }
+Else
+  Extrude{0,0,0.3}{ Surface{1:3}; }
+  BooleanFragments{ Volume{1}; Delete; }{ Volume{2:3}; Delete; }
+  Delete{ Surface{1:3}; }
+EndIf
diff --git a/demos/boolean/revolve.geo b/demos/boolean/revolve.geo
new file mode 100644
index 0000000000000000000000000000000000000000..8f8ca8062b7bc65039efe62197cf3e59d7e59832
--- /dev/null
+++ b/demos/boolean/revolve.geo
@@ -0,0 +1,38 @@
+SetFactory("OpenCASCADE");
+
+Mesh.Algorithm = 6;
+Mesh.CharacteristicLengthMin = 0.1;
+Mesh.CharacteristicLengthMax = 0.1;
+
+Point(1) = {0,0,0};
+Point(2) = {1,0,0};
+Point(3) = {1,1,0};
+Point(4) = {0,1,0};
+Line(1) = {1,2};
+Line(2) = {2,3};
+Line(3) = {3,4};
+Line(4) = {4,1};
+Line Loop(1) = {1,2,3,4};
+Plane Surface(1) = {1};
+
+Point(5) = {0.2,0.2,0};
+Point(6) = {0.5,0.2,0};
+Point(7) = {0.5,0.5,0};
+Point(8) = {0.2,0.5,0};
+Line(5) = {5,6};
+Line(6) = {6,7};
+Line(7) = {7,8};
+Line(8) = {8,5};
+Line Loop(2) = {5,6,7,8};
+Plane Surface(2) = {2};
+
+Disk(3) = {0.6, 0.6, 0, 0.5, 0.3};
+
+DefineConstant[
+  angle = {90, Min 0, Max 360, Step 1,
+    Name "Parameters/Angle"}
+];
+BooleanFragments{ Surface{1}; Delete; }{ Surface{2:3}; Delete; }
+a() = Extrude{ {0,1,0}, {0,0,0}, angle*2*Pi/360 }{ Surface{1:5}; };
+
+