Code coverage tests

This page documents the degree to which the PARI/GP source code is tested by our public test suite, distributed with the source distribution in directory src/test/. This is measured by the gcov utility; we then process gcov output using the lcov frond-end.

We test a few variants depending on Configure flags on the pari.math.u-bordeaux.fr machine (x86_64 architecture), and agregate them in the final report:

The target is to exceed 90% coverage for all mathematical modules (given that branches depending on DEBUGLEVEL or DEBUGMEM are not covered). This script is run to produce the results below.

LCOV - code coverage report
Current view: top level - basemath - concat.c (source / functions) Hit Total Coverage
Test: PARI/GP v2.18.0 lcov report (development 29818-b3e15d99d2) Lines: 331 358 92.5 %
Date: 2024-12-27 09:09:37 Functions: 15 15 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* Copyright (C) 2000  The PARI group.
       2             : 
       3             : This file is part of the PARI/GP package.
       4             : 
       5             : PARI/GP is free software; you can redistribute it and/or modify it under the
       6             : terms of the GNU General Public License as published by the Free Software
       7             : Foundation; either version 2 of the License, or (at your option) any later
       8             : version. It is distributed in the hope that it will be useful, but WITHOUT
       9             : ANY WARRANTY WHATSOEVER.
      10             : 
      11             : Check the License for details. You should have received a copy of it, along
      12             : with the package; see the file 'COPYING'. If not, write to the Free Software
      13             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
      14             : 
      15             : /*******************************************************************/
      16             : /*                                                                 */
      17             : /*                          CONCATENATION                          */
      18             : /*                                                                 */
      19             : /*******************************************************************/
      20             : #include "pari.h"
      21             : #include "paripriv.h"
      22             : 
      23             : /* assume A or B is a t_LIST */
      24             : static GEN
      25          21 : listconcat(GEN A, GEN B)
      26             : {
      27             :   long i, l1, lx;
      28             :   GEN L, z, L1, L2;
      29             : 
      30          21 :   if (typ(A) != t_LIST) {
      31           7 :     if (list_typ(B)!=t_LIST_RAW) pari_err_TYPE("listconcat",B);
      32           7 :     L2 = list_data(B);
      33           7 :     if (!L2) return mklistcopy(A);
      34           7 :     lx = lg(L2) + 1;
      35           7 :     z = mklist();
      36           7 :     list_data(z) = L = cgetg(lx, t_VEC);
      37          35 :     for (i = 2; i < lx; i++) gel(L,i) = gcopy(gel(L2,i-1));
      38           7 :     gel(L,1) = gcopy(A); return z;
      39          14 :   } else if (typ(B) != t_LIST) {
      40           7 :     if (list_typ(A)!=t_LIST_RAW) pari_err_TYPE("listconcat",A);
      41           7 :     L1 = list_data(A);
      42           7 :     if (!L1) return mklistcopy(B);
      43           7 :     lx = lg(L1) + 1;
      44           7 :     z = mklist();
      45           7 :     list_data(z) = L = cgetg(lx, t_VEC);
      46          35 :     for (i = 1; i < lx-1; i++) gel(L,i) = gcopy(gel(L1,i));
      47           7 :     gel(L,i) = gcopy(B); return z;
      48             :   }
      49             :   /* A, B both t_LISTs */
      50           7 :   if (list_typ(A)!=t_LIST_RAW) pari_err_TYPE("listconcat",A);
      51           7 :   if (list_typ(B)!=t_LIST_RAW) pari_err_TYPE("listconcat",B);
      52           7 :   L1 = list_data(A); if (!L1) return listcopy(B);
      53           7 :   L2 = list_data(B); if (!L2) return listcopy(A);
      54             : 
      55           7 :   l1 = lg(L1);
      56           7 :   lx = l1-1 + lg(L2);
      57           7 :   z = mklist();
      58           7 :   list_data(z) = L = cgetg(lx, t_VEC);
      59           7 :   L2 -= l1-1;
      60          35 :   for (i=1; i<l1; i++) gel(L,i) = gcopy(gel(L1,i));
      61          35 :   for (   ; i<lx; i++) gel(L,i) = gcopy(gel(L2,i));
      62           7 :   return z;
      63             : }
      64             : 
      65             : /* assume A or B is a t_STR */
      66             : static GEN
      67         427 : strconcat(GEN x, GEN y)
      68             : {
      69             :   size_t l, lx;
      70         427 :   char *sx = GENtostr_unquoted(x);
      71         427 :   char *sy = GENtostr_unquoted(y), *str;
      72         427 :   lx = strlen(sx);
      73         427 :   l = nchar2nlong(lx + strlen(sy) + 1);
      74         427 :   x = cgetg(l + 1, t_STR); str = GSTR(x);
      75         427 :   strcpy(str,   sx);
      76         427 :   strcpy(str+lx,sy); return x;
      77             : }
      78             : 
      79             : /* concat A and B vertically. Internal */
      80             : GEN
      81    20304219 : vconcat(GEN A, GEN B)
      82             : {
      83             :   long la, ha, hb, hc, i, j, T;
      84             :   GEN M, a, b, c;
      85             : 
      86    20304219 :   if (!A) return B;
      87    20267476 :   if (!B) return A;
      88    20267476 :   la = lg(A); if (la==1) return B;
      89    20208406 :   T = typ(gel(A,1)); /* t_COL or t_VECSMALL */
      90    20208406 :   ha = lgcols(A); M = cgetg(la,t_MAT);
      91    20208773 :   hb = lgcols(B); hc = ha+hb-1;
      92   251700303 :   for (j=1; j<la; j++)
      93             :   {
      94   231490708 :     c = cgetg(hc, T); gel(M, j) = c;
      95   231481987 :     a = gel(A,j);
      96   231481987 :     b = gel(B,j);
      97  1035521908 :     for (i=1; i<ha; i++) *++c = *++a;
      98  1029492826 :     for (i=1; i<hb; i++) *++c = *++b;
      99             :   }
     100    20209595 :   return M;
     101             : }
     102             : 
     103             : static void
     104          49 : err_cat(GEN x, GEN y) { pari_err_OP("concatenation",x,y); }
     105             : 
     106             : GEN
     107    24519369 : shallowconcat(GEN x, GEN y)
     108             : {
     109    24519369 :   long tx=typ(x),ty=typ(y),lx=lg(x),ly=lg(y),i;
     110             :   GEN z,p1;
     111             : 
     112    24519369 :   if (tx==t_STR  || ty==t_STR)  return strconcat(x,y);
     113    24519468 :   if (tx==t_LIST || ty==t_LIST) return listconcat(x,y);
     114             : 
     115    24519472 :   if (tx==t_MAT && lx==1)
     116             :   {
     117      194976 :     if (ty!=t_VEC) return gtomat(y);
     118           0 :     if (ly==1) return cgetg(1, t_MAT);
     119           0 :     err_cat(x,y);
     120             :   }
     121    24324496 :   if (ty==t_MAT && ly==1)
     122             :   {
     123      165409 :     if (tx!=t_VEC) return gtomat(x);
     124           0 :     if (lx==1) return cgetg(1, t_MAT);
     125           0 :     err_cat(x,y);
     126             :   }
     127             : 
     128    24159577 :   if (tx == ty)
     129             :   {
     130    15988310 :     if (tx == t_MAT)
     131    12701466 :     { if (lgcols(x) != lgcols(y)) err_cat(x,y); }
     132             :     else
     133     3286844 :       if (!is_matvec_t(tx) && tx != t_VECSMALL) return mkvec2(x, y);
     134    15988267 :     z=cgetg(lx+ly-1,tx);
     135   177447685 :     for (i=1; i<lx; i++) z[i]     = x[i];
     136    82291350 :     for (i=1; i<ly; i++) z[lx+i-1]= y[i];
     137    15988189 :     return z;
     138             :   }
     139             : 
     140     8171267 :   if (! is_matvec_t(tx))
     141             :   {
     142       20480 :     if (! is_matvec_t(ty)) return mkvec2(x, y);
     143       20480 :     z=cgetg(ly+1,ty);
     144       20480 :     if (ty != t_MAT) p1 = x;
     145             :     else
     146             :     {
     147           0 :       if (lgcols(y)!=2) err_cat(x,y);
     148           0 :       p1 = mkcol(x);
     149             :     }
     150       66886 :     for (i=2; i<=ly; i++) z[i] = y[i-1];
     151       20480 :     gel(z, 1) = p1; return z;
     152             :   }
     153     8150783 :   if (! is_matvec_t(ty))
     154             :   {
     155     1521217 :     z=cgetg(lx+1,tx);
     156     1521217 :     if (tx != t_MAT) p1 = y;
     157             :     else
     158             :     {
     159           0 :       if (lgcols(x)!=2) err_cat(x,y);
     160           0 :       p1 = mkcol(y);
     161             :     }
     162    39755362 :     for (i=1; i<lx; i++) z[i]=x[i];
     163     1521217 :     gel(z, lx) = p1; return z;
     164             :   }
     165             : 
     166     6629523 :   switch(tx)
     167             :   {
     168       16534 :     case t_VEC:
     169             :       switch(ty)
     170             :       {
     171       16534 :         case t_COL:
     172       16534 :           if (lx<=2) return (lx==1)? y: shallowconcat(gel(x,1),y);
     173           0 :           if (ly>=3) break;
     174           0 :           return (ly==1)? x: shallowconcat(x,gel(y,1));
     175           0 :         case t_MAT:
     176           0 :           z=cgetg(ly,t_MAT); if (lx != ly) break;
     177           0 :           for (i=1; i<ly; i++) gel(z,i) = shallowconcat(gel(x,i),gel(y,i));
     178           0 :           return z;
     179             :       }
     180           0 :       break;
     181             : 
     182      107431 :     case t_COL:
     183             :       switch(ty)
     184             :       {
     185         379 :         case t_VEC:
     186         379 :           if (lx<=2) return (lx==1)? y: shallowconcat(gel(x,1), y);
     187         176 :           if (ly>=3) break;
     188         176 :           return (ly==1)? x: shallowconcat(x, gel(y,1));
     189      107052 :         case t_MAT:
     190      107052 :           if (lx != lgcols(y)) break;
     191      107052 :           z=cgetg(ly+1,t_MAT);  gel(z,1) = x;
     192      664569 :           for (i=2; i<=ly; i++) gel(z,i) = gel(y,i-1);
     193      107052 :           return z;
     194             :       }
     195           0 :       break;
     196             : 
     197     6505556 :     case t_MAT:
     198             :       switch(ty)
     199             :       {
     200           0 :         case t_VEC:
     201           0 :           z=cgetg(lx, t_MAT); if (ly != lx) break;
     202           0 :           for (i=1; i<lx; i++) gel(z,i) = shallowconcat(gel(x,i), gel(y,i));
     203           0 :           return z;
     204     6505549 :         case t_COL:
     205     6505549 :           if (ly != lgcols(x)) break;
     206     6505013 :           z=cgetg(lx+1,t_MAT); gel(z,lx) = y;
     207    23478402 :           for (i=1; i<lx; i++) z[i]=x[i];
     208     6505640 :           return z;
     209             :       }
     210           7 :       break;
     211             :   }
     212           9 :   err_cat(x,y);
     213             :   return NULL; /* LCOV_EXCL_LINE */
     214             : }
     215             : 
     216             : /* see catmany() */
     217             : static GEN
     218       19322 : catmanyMAT(GEN y1, GEN y2)
     219             : {
     220       19322 :   long i, h = 0, L = 1;
     221             :   GEN z, y;
     222       67033 :   for (y = y2; y >= y1; y--)
     223             :   {
     224       47711 :     GEN c = gel(y,0);
     225       47711 :     long nc = lg(c)-1;
     226       47711 :     if (nc == 0) continue;
     227       47683 :     if (h != lgcols(c))
     228             :     {
     229       19315 :       if (h) err_cat(gel(y2,0), c);
     230       19315 :       h = lgcols(c);
     231             :     }
     232       47683 :     L += nc;
     233       47683 :     z = new_chunk(nc) - 1;
     234      166766 :     for (i=1; i<=nc; i++) gel(z,i) = gel(c,i);
     235             :   }
     236       19322 :   z = new_chunk(1);
     237       19322 :   *z = evaltyp(t_MAT) | evallg(L);
     238       19322 :   return z;
     239             : }
     240             : static GEN
     241         147 : catmanySTR(GEN y1, GEN y2)
     242             : {
     243         147 :   long L = 1; /* final \0 */
     244             :   GEN z, y;
     245             :   char *s;
     246        7336 :   for (y = y1; y <= y2; y++)
     247             :   {
     248        7189 :     char *c = GSTR( gel(y,0) );
     249        7189 :     L += strlen(c);
     250             :   }
     251         147 :   z = cgetg(nchar2nlong(L)+1, t_STR);
     252         147 :   s = GSTR(z);
     253        7336 :   for (y = y1; y <= y2; y++)
     254             :   {
     255        7189 :     char *c = GSTR( gel(y,0) );
     256        7189 :     long nc = strlen(c);
     257        7189 :     if (nc) { (void)memcpy(s, c, nc); s += nc; }
     258             :   }
     259         147 :   *s = 0; return z;
     260             : }
     261             : 
     262             : /* all entries in y have the same type t = t_VEC, COL, MAT or VECSMALL
     263             :  * concatenate y[k1..k2], with yi = y + ki, k1 <= k2 */
     264             : static GEN
     265     2122566 : catmany(GEN y1, GEN y2, long t)
     266             : {
     267             :   long i, L;
     268             :   GEN z, y;
     269     2122566 :   if (y1 == y2) return gel(y1,0);
     270     2120466 :   if (t == t_MAT) return catmanyMAT(y1, y2);
     271     2101144 :   if (t == t_STR) return catmanySTR(y1, y2);
     272     2100997 :   L = 1;
     273     7856796 :   for (y = y2; y >= y1; y--)
     274             :   {
     275     5755787 :     GEN c = gel(y,0);
     276     5755787 :     long nc = lg(c)-1;
     277     5755787 :     if (nc == 0) continue;
     278     5194061 :     L += nc;
     279     5194061 :     z = new_chunk(nc) - 1;
     280    17088415 :     for (i=1; i<=nc; i++) gel(z,i) = gel(c,i);
     281             :   }
     282     2101009 :   z = new_chunk(1);
     283     2101010 :   *z = evaltyp(t) | evallg(L);
     284     2101010 :   return z;
     285             : }
     286             : 
     287             : GEN
     288     7801087 : shallowconcat1(GEN x)
     289             : {
     290     7801087 :   pari_sp av = avma;
     291             :   long lx, t, i;
     292             :   GEN z;
     293     7801087 :   switch(typ(x))
     294             :   {
     295     7801071 :     case t_VEC: case t_COL:
     296     7801071 :       lx = lg(x);
     297     7801071 :       break;
     298          21 :     case t_LIST:
     299          21 :       if (list_typ(x)!=t_LIST_RAW) pari_err_TYPE("concat",x);
     300          21 :       if (!list_data(x)) pari_err_DOMAIN("concat","vector","=",x,x);
     301           7 :       x = list_data(x); lx = lg(x);
     302           7 :       break;
     303           0 :     default:
     304           0 :       pari_err_TYPE("concat",x);
     305             :       return NULL; /* LCOV_EXCL_LINE */
     306             :   }
     307     7801078 :   if (lx==1) pari_err_DOMAIN("concat","vector","=",x,x);
     308     7801117 :   if (lx==2) return gel(x,1);
     309     2122580 :   z = gel(x,1); t = typ(z); i = 2;
     310     2122580 :   if (is_matvec_t(t) || t == t_VECSMALL || t == t_STR)
     311             :   { /* detect a "homogeneous" object: catmany is faster */
     312     5812815 :     for (; i<lx; i++)
     313     3692572 :       if (typ(gel(x,i)) != t) break;
     314     2122567 :     z = catmany(x + 1, x + i-1, t);
     315             :   }
     316     2125547 :   for (; i<lx; i++) {
     317        2954 :     z = shallowconcat(z, gel(x,i));
     318        2954 :     if (gc_needed(av,3))
     319             :     {
     320           0 :       if (DEBUGMEM>1) pari_warn(warnmem,"concat: i = %ld", i);
     321           0 :       z = gerepilecopy(av, z);
     322             :     }
     323             :   }
     324     2122593 :   return z;
     325             : }
     326             : 
     327             : GEN
     328         840 : gconcat1(GEN x)
     329             : {
     330         840 :   pari_sp av = avma;
     331         840 :   return gerepilecopy(av, shallowconcat1(x));
     332             : }
     333             : 
     334             : /* fill M[xoff+i, yoff+j] with the contents of c ( c * Id_n if scalar ) */
     335             : static void
     336    16630301 : matfill(GEN M, GEN c, long xoff, long yoff, long n)
     337             : {
     338             :   long i, j, h, l;
     339    16630301 :   l = lg(c); if (l == 1) return;
     340    16603977 :   switch(typ(c))
     341             :   {
     342       44275 :     case t_VEC:
     343     1032605 :       for (i = 1; i < l; i++)
     344      988330 :         gcoeff(M,xoff+1,yoff+i) = gel(c,i);
     345       44275 :       break;
     346      161573 :     case t_COL:
     347     1187757 :       for (i = 1; i < l; i++)
     348     1026184 :         gcoeff(M,xoff+i,yoff+1) = gel(c,i);
     349      161573 :       break;
     350     9339995 :     case t_MAT:
     351     9339995 :       h = lgcols(c);
     352    27704688 :       for (j = 1; j < l; j++)
     353    74201862 :         for (i = 1; i < h; i++) gcoeff(M,xoff+i,yoff+j) = gcoeff(c,i,j);
     354     9339994 :       break;
     355     7058134 :     default:
     356    15932135 :       for (i = 1; i <= n; i++)
     357     8874001 :         gcoeff(M, xoff+i, yoff+i) = c;
     358     7058134 :       break;
     359             :   }
     360             : }
     361             : 
     362             : static GEN
     363    18743503 : _matsize(GEN x)
     364             : {
     365    18743503 :   long t = typ(x), L = lg(x) - 1;
     366    18743503 :   switch(t)
     367             :   { /* matsize */
     368       88564 :     case t_VEC: return mkvecsmall2(1, L);
     369      323090 :     case t_COL: return mkvecsmall2(L, 1);
     370    11272630 :     case t_MAT: return mkvecsmall2(L? nbrows(x): 0, L);
     371     7059219 :     default:
     372     7059219 :       if (is_noncalc_t(t)) pari_err_TYPE("_matsize", x);
     373     7059214 :       return mkvecsmall2(1, 1);
     374             :   }
     375             : }
     376             : 
     377             : GEN
     378     3683031 : shallowmatconcat(GEN v)
     379             : {
     380     3683031 :   long i, j, h, l = lg(v), L = 0, H = 0;
     381             :   GEN M, maxh, maxl;
     382     3683031 :   if (l == 1) return cgetg(1,t_MAT);
     383     3678777 :   switch(typ(v))
     384             :   {
     385      995688 :     case t_VEC:
     386     3062892 :       for (i = 1; i < l; i++)
     387             :       {
     388     2067206 :         GEN c = gel(v,i);
     389     2067206 :         GEN s = _matsize(c);
     390     2067206 :         H = maxss(H, s[1]);
     391     2067204 :         L += s[2];
     392             :       }
     393      995686 :       M = zeromatcopy(H, L);
     394      995698 :       L = 0;
     395     3062932 :       for (i = 1; i < l; i++)
     396             :       {
     397     2067232 :         GEN c = gel(v,i);
     398     2067232 :         GEN s = _matsize(c);
     399     2067239 :         matfill(M, c, 0, L, 1);
     400     2067234 :         L += s[2];
     401             :       }
     402      995700 :       return M;
     403             : 
     404        3619 :     case t_COL:
     405       49693 :       for (i = 1; i < l; i++)
     406             :       {
     407       46074 :         GEN c = gel(v,i);
     408       46074 :         GEN s = _matsize(c);
     409       46074 :         H += s[1];
     410       46074 :         L = maxss(L, s[2]);
     411             :       }
     412        3619 :       M = zeromatcopy(H, L);
     413        3619 :       H = 0;
     414       49693 :       for (i = 1; i < l; i++)
     415             :       {
     416       46074 :         GEN c = gel(v,i);
     417       46074 :         GEN s = _matsize(c);
     418       46074 :         matfill(M, c, H, 0, 1);
     419       46074 :         H += s[1];
     420             :       }
     421        3619 :       return M;
     422     2679470 :     case t_MAT:
     423     2679470 :       h = lgcols(v);
     424     2679470 :       maxh = zero_zv(h-1);
     425     2679469 :       maxl = zero_zv(l-1);
     426     8798202 :       for (j = 1; j < l; j++)
     427    20635710 :         for (i = 1; i < h; i++)
     428             :         {
     429    14516978 :           GEN c = gcoeff(v,i,j);
     430    14516978 :           GEN s = _matsize(c);
     431    14516977 :           if (s[1] > maxh[i]) maxh[i] = s[1];
     432    14516977 :           if (s[2] > maxl[j]) maxl[j] = s[2];
     433             :         }
     434     8798212 :       for (i = 1, H = 0; i < h; i++) H += maxh[i];
     435     8798205 :       for (j = 1, L = 0; j < l; j++) L += maxl[j];
     436     2679469 :       M = zeromatcopy(H, L);
     437     8798209 :       for (j = 1, L = 0; j < l; j++)
     438             :       {
     439    20635733 :         for (i = 1, H = 0; i < h; i++)
     440             :         {
     441    14516995 :           GEN c = gcoeff(v,i,j);
     442    14516995 :           matfill(M, c, H, L, minss(maxh[i], maxl[j]));
     443    14516994 :           H += maxh[i];
     444             :         }
     445     6118738 :         L += maxl[j];
     446             :       }
     447     2679470 :       return M;
     448           0 :     default:
     449           0 :       pari_err_TYPE("shallowmatconcat", v);
     450             :       return NULL;/*LCOV_EXCL_LINE*/
     451             :   }
     452             : }
     453             : GEN
     454       76580 : matconcat(GEN v)
     455             : {
     456       76580 :   pari_sp av = avma;
     457       76580 :   return gerepilecopy(av, shallowmatconcat(v));
     458             : }
     459             : 
     460             : GEN
     461    19425192 : gconcat(GEN x, GEN y)
     462             : {
     463             :   long tx, lx,ty,ly,i;
     464             :   GEN z,p1;
     465             : 
     466    19425192 :   if (!y) return gconcat1(x);
     467    19424352 :   tx = typ(x);
     468    19424352 :   ty = typ(y);
     469    19424352 :   if (tx==t_STR  || ty==t_STR)
     470             :   {
     471           7 :     pari_sp av = avma;
     472           7 :     return gerepileuptoleaf(av, strconcat(x,y));
     473             :   }
     474    19424345 :   if (tx==t_LIST || ty==t_LIST) return listconcat(x,y);
     475    19424324 :   lx=lg(x); ly=lg(y);
     476             : 
     477    19424324 :   if (tx==t_MAT && lx==1)
     478             :   {
     479         588 :     if (ty!=t_VEC) return gtomat(y);
     480          21 :     if (ly==1) return cgetg(1, t_MAT);
     481           7 :     err_cat(x,y);
     482             :   }
     483    19423736 :   if (ty==t_MAT && ly==1)
     484             :   {
     485          21 :     if (tx!=t_VEC) return gtomat(x);
     486          14 :     if (lx==1) return cgetg(1, t_MAT);
     487           7 :     err_cat(x,y);
     488             :   }
     489             : 
     490    19423715 :   if (tx == ty)
     491             :   {
     492      653415 :     if (tx == t_MAT && lgcols(x) != lgcols(y)) err_cat(x,y);
     493      653415 :     if (!is_matvec_t(tx))
     494             :     {
     495         210 :       if (tx != t_VECSMALL) return mkvec2copy(x, y);
     496         203 :       z = cgetg(lx+ly-1,t_VECSMALL);
     497         301 :       for (i=1; i<lx; i++) z[i]     = x[i];
     498         294 :       for (i=1; i<ly; i++) z[lx+i-1]= y[i];
     499         203 :       return z;
     500             :     }
     501      653205 :     z=cgetg(lx+ly-1,tx);
     502     3303964 :     for (i=1; i<lx; i++) gel(z,i)     = gcopy(gel(x,i));
     503     2529400 :     for (i=1; i<ly; i++) gel(z,lx+i-1)= gcopy(gel(y,i));
     504      653205 :     return z;
     505             :   }
     506             : 
     507    18770300 :   if (! is_matvec_t(tx))
     508             :   {
     509         168 :     if (! is_matvec_t(ty)) return mkvec2copy(x, y);
     510         168 :     z=cgetg(ly+1,ty);
     511         168 :     if (ty != t_MAT) p1 = gcopy(x);
     512             :     else
     513             :     {
     514          14 :       if (lgcols(y)!=2) err_cat(x,y);
     515           7 :       p1 = mkcolcopy(x);
     516             :     }
     517        3514 :     for (i=2; i<=ly; i++) gel(z,i) = gcopy(gel(y,i-1));
     518         161 :     gel(z,1) = p1; return z;
     519             :   }
     520    18770132 :   if (! is_matvec_t(ty))
     521             :   {
     522    18770034 :     z=cgetg(lx+1,tx);
     523    18770034 :     if (tx != t_MAT) p1 = gcopy(y);
     524             :     else
     525             :     {
     526          14 :       if (lgcols(x)!=2) err_cat(x,y);
     527           7 :       p1 = mkcolcopy(y);
     528             :     }
     529  2547662320 :     for (i=1; i<lx; i++) gel(z,i) = gcopy(gel(x,i));
     530    18770027 :     gel(z,lx) = p1; return z;
     531             :   }
     532             : 
     533          98 :   switch(tx)
     534             :   {
     535          35 :     case t_VEC:
     536             :       switch(ty)
     537             :       {
     538          28 :         case t_COL:
     539          28 :           if (lx<=2) return (lx==1)? gcopy(y): gconcat(gel(x,1),y);
     540          28 :           if (ly>=3) break;
     541          14 :           return (ly==1)? gcopy(x): gconcat(x,gel(y,1));
     542           7 :         case t_MAT:
     543           7 :           z=cgetg(ly,t_MAT); if (lx != ly) break;
     544          21 :           for (i=1; i<ly; i++) gel(z,i) = gconcat(gel(x,i),gel(y,i));
     545           7 :           return z;
     546             :       }
     547          14 :       break;
     548             : 
     549          49 :     case t_COL:
     550             :       switch(ty)
     551             :       {
     552          42 :         case t_VEC:
     553          42 :           if (lx<=2) return (lx==1)? gcopy(y): gconcat(gel(x,1),y);
     554          28 :           if (ly>=3) break;
     555          21 :           return (ly==1)? gcopy(x): gconcat(x,gel(y,1));
     556           7 :         case t_MAT:
     557           7 :           if (lx != lgcols(y)) break;
     558           7 :           z=cgetg(ly+1,t_MAT); gel(z,1) = gcopy(x);
     559          14 :           for (i=2; i<=ly; i++) gel(z,i) = gcopy(gel(y,i-1));
     560           7 :           return z;
     561             :       }
     562           7 :       break;
     563             : 
     564          14 :     case t_MAT:
     565             :       switch(ty)
     566             :       {
     567           7 :         case t_VEC:
     568           7 :           z=cgetg(lx,t_MAT); if (ly != lx) break;
     569          21 :           for (i=1; i<lx; i++) gel(z,i) = gconcat(gel(x,i),gel(y,i));
     570           7 :           return z;
     571           7 :         case t_COL:
     572           7 :           if (ly != lgcols(x)) break;
     573           7 :           z=cgetg(lx+1,t_MAT); gel(z,lx) = gcopy(y);
     574          14 :           for (i=1; i<lx; i++) gel(z,i) = gcopy(gel(x,i));
     575           7 :           return z;
     576             :       }
     577           0 :       break;
     578             :   }
     579          21 :   err_cat(x,y);
     580             :   return NULL; /* LCOV_EXCL_LINE */
     581             : }

Generated by: LCOV version 1.16