PageRenderTime 137ms CodeModel.GetById 31ms app.highlight 68ms RepoModel.GetById 12ms app.codeStats 0ms

/src/mesch/memory.c

https://bitbucket.org/yarikoptic/nrn
C | 1004 lines | 693 code | 191 blank | 120 comment | 149 complexity | e0bb9563342844e4e358fabaf79b69d9 MD5 | raw file
   1#include <../../nrnconf.h>
   2
   3/**************************************************************************
   4**
   5** Copyright (C) 1993 David E. Steward & Zbigniew Leyk, all rights reserved.
   6**
   7**			     Meschach Library
   8** 
   9** This Meschach Library is provided "as is" without any express 
  10** or implied warranty of any kind with respect to this software. 
  11** In particular the authors shall not be liable for any direct, 
  12** indirect, special, incidental or consequential damages arising 
  13** in any way from use of the software.
  14** 
  15** Everyone is granted permission to copy, modify and redistribute this
  16** Meschach Library, provided:
  17**  1.  All copies contain this copyright notice.
  18**  2.  All modified copies shall carry a notice stating who
  19**      made the last modification and the date of such modification.
  20**  3.  No charge is made for this software or works derived from it.  
  21**      This clause shall not be construed as constraining other software
  22**      distributed on the same medium as this software, nor is a
  23**      distribution fee considered a charge.
  24**
  25***************************************************************************/
  26
  27
  28/* memory.c 1.3 11/25/87 */
  29
  30#include 	"matrix.h"
  31
  32
  33static	char	rcsid[] = "memory.c,v 1.1 1997/12/04 17:55:38 hines Exp";
  34
  35/* m_get -- gets an mxn matrix (in MAT form) by dynamic memory allocation */
  36MAT	*m_get(m,n)
  37int	m,n;
  38{
  39   MAT	*matrix;
  40   int	i;
  41   
  42   if (m < 0 || n < 0)
  43     error(E_NEG,"m_get");
  44
  45   if ((matrix=NEW(MAT)) == (MAT *)NULL )
  46     error(E_MEM,"m_get");
  47   else if (mem_info_is_on()) {
  48      mem_bytes(TYPE_MAT,0,sizeof(MAT));
  49      mem_numvar(TYPE_MAT,1);
  50   }
  51   
  52   matrix->m = m;		matrix->n = matrix->max_n = n;
  53   matrix->max_m = m;	matrix->max_size = m*n;
  54#ifndef SEGMENTED
  55   if ((matrix->base = NEW_A(m*n,Real)) == (Real *)NULL )
  56   {
  57      free(matrix);
  58      error(E_MEM,"m_get");
  59   }
  60   else if (mem_info_is_on()) {
  61      mem_bytes(TYPE_MAT,0,m*n*sizeof(Real));
  62   }
  63#else
  64   matrix->base = (Real *)NULL;
  65#endif
  66   if ((matrix->me = (Real **)calloc(m,sizeof(Real *))) == 
  67       (Real **)NULL )
  68   {	free(matrix->base);	free(matrix);
  69	error(E_MEM,"m_get");
  70     }
  71   else if (mem_info_is_on()) {
  72      mem_bytes(TYPE_MAT,0,m*sizeof(Real *));
  73   }
  74   
  75#ifndef SEGMENTED
  76   /* set up pointers */
  77   for ( i=0; i<m; i++ )
  78     matrix->me[i] = &(matrix->base[i*n]);
  79#else
  80   for ( i = 0; i < m; i++ )
  81     if ( (matrix->me[i]=NEW_A(n,Real)) == (Real *)NULL )
  82       error(E_MEM,"m_get");
  83     else if (mem_info_is_on()) {
  84	mem_bytes(TYPE_MAT,0,n*sizeof(Real));
  85       }
  86#endif
  87   
  88   return (matrix);
  89}
  90
  91
  92/* px_get -- gets a PERM of given 'size' by dynamic memory allocation
  93   -- Note: initialized to the identity permutation */
  94PERM	*px_get(size)
  95int	size;
  96{
  97   PERM	*permute;
  98   int	i;
  99
 100   if (size < 0)
 101     error(E_NEG,"px_get");
 102
 103   if ((permute=NEW(PERM)) == (PERM *)NULL )
 104     error(E_MEM,"px_get");
 105   else if (mem_info_is_on()) {
 106      mem_bytes(TYPE_PERM,0,sizeof(PERM));
 107      mem_numvar(TYPE_PERM,1);
 108   }
 109   
 110   permute->size = permute->max_size = size;
 111   if ((permute->pe = NEW_A(size,u_int)) == (u_int *)NULL )
 112     error(E_MEM,"px_get");
 113   else if (mem_info_is_on()) {
 114      mem_bytes(TYPE_PERM,0,size*sizeof(u_int));
 115   }
 116   
 117   for ( i=0; i<size; i++ )
 118     permute->pe[i] = i;
 119   
 120   return (permute);
 121}
 122
 123/* v_get -- gets a VEC of dimension 'dim'
 124   -- Note: initialized to zero */
 125VEC	*v_get(size)
 126int	size;
 127{
 128   VEC	*vector;
 129   
 130   if (size < 0)
 131     error(E_NEG,"v_get");
 132
 133   if ((vector=NEW(VEC)) == (VEC *)NULL )
 134     error(E_MEM,"v_get");
 135   else if (mem_info_is_on()) {
 136      mem_bytes(TYPE_VEC,0,sizeof(VEC));
 137      mem_numvar(TYPE_VEC,1);
 138   }
 139   
 140   vector->dim = vector->max_dim = size;
 141   if ((vector->ve=NEW_A(size,Real)) == (Real *)NULL )
 142   {
 143      free(vector);
 144      error(E_MEM,"v_get");
 145   }
 146   else if (mem_info_is_on()) {
 147      mem_bytes(TYPE_VEC,0,size*sizeof(Real));
 148   }
 149   
 150   return (vector);
 151}
 152
 153/* m_free -- returns MAT & asoociated memory back to memory heap */
 154int	m_free(mat)
 155MAT	*mat;
 156{
 157#ifdef SEGMENTED
 158   int	i;
 159#endif
 160   
 161   if ( mat==(MAT *)NULL || (int)(mat->m) < 0 ||
 162       (int)(mat->n) < 0 )
 163     /* don't trust it */
 164     return (-1);
 165   
 166#ifndef SEGMENTED
 167   if ( mat->base != (Real *)NULL ) {
 168      if (mem_info_is_on()) {
 169	 mem_bytes(TYPE_MAT,mat->max_m*mat->max_n*sizeof(Real),0);
 170      }
 171      free((char *)(mat->base));
 172   }
 173#else
 174   for ( i = 0; i < mat->max_m; i++ )
 175     if ( mat->me[i] != (Real *)NULL ) {
 176	if (mem_info_is_on()) {
 177	   mem_bytes(TYPE_MAT,mat->max_n*sizeof(Real),0);
 178	}
 179	free((char *)(mat->me[i]));
 180     }
 181#endif
 182   if ( mat->me != (Real **)NULL ) {
 183      if (mem_info_is_on()) {
 184	 mem_bytes(TYPE_MAT,mat->max_m*sizeof(Real *),0);
 185      }
 186      free((char *)(mat->me));
 187   }
 188   
 189   if (mem_info_is_on()) {
 190      mem_bytes(TYPE_MAT,sizeof(MAT),0);
 191      mem_numvar(TYPE_MAT,-1);
 192   }
 193   free((char *)mat);
 194   
 195   return (0);
 196}
 197
 198
 199
 200/* px_free -- returns PERM & asoociated memory back to memory heap */
 201int	px_free(px)
 202PERM	*px;
 203{
 204   if ( px==(PERM *)NULL || (int)(px->size) < 0 )
 205     /* don't trust it */
 206     return (-1);
 207   
 208   if ( px->pe == (u_int *)NULL ) {
 209      if (mem_info_is_on()) {
 210	 mem_bytes(TYPE_PERM,sizeof(PERM),0);
 211	 mem_numvar(TYPE_PERM,-1);
 212      }      
 213      free((char *)px);
 214   }
 215   else
 216   {
 217      if (mem_info_is_on()) {
 218	 mem_bytes(TYPE_PERM,sizeof(PERM)+px->max_size*sizeof(u_int),0);
 219	 mem_numvar(TYPE_PERM,-1);
 220      }
 221      free((char *)px->pe);
 222      free((char *)px);
 223   }
 224   
 225   return (0);
 226}
 227
 228
 229
 230/* v_free -- returns VEC & asoociated memory back to memory heap */
 231int	v_free(vec)
 232VEC	*vec;
 233{
 234   if ( vec==(VEC *)NULL || (int)(vec->dim) < 0 )
 235     /* don't trust it */
 236     return (-1);
 237   
 238   if ( vec->ve == (Real *)NULL ) {
 239      if (mem_info_is_on()) {
 240	 mem_bytes(TYPE_VEC,sizeof(VEC),0);
 241	 mem_numvar(TYPE_VEC,-1);
 242      }
 243      free((char *)vec);
 244   }
 245   else
 246   {
 247      if (mem_info_is_on()) {
 248	 mem_bytes(TYPE_VEC,sizeof(VEC)+vec->max_dim*sizeof(Real),0);
 249	 mem_numvar(TYPE_VEC,-1);
 250      }
 251      free((char *)vec->ve);
 252      free((char *)vec);
 253   }
 254   
 255   return (0);
 256}
 257
 258
 259
 260/* m_resize -- returns the matrix A of size new_m x new_n; A is zeroed
 261   -- if A == NULL on entry then the effect is equivalent to m_get() */
 262MAT	*m_resize(A,new_m,new_n)
 263MAT	*A;
 264int	new_m, new_n;
 265{
 266   int	i;
 267   int	new_max_m, new_max_n, new_size, old_m, old_n;
 268   
 269   if (new_m < 0 || new_n < 0)
 270     error(E_NEG,"m_resize");
 271
 272   if ( ! A )
 273     return m_get(new_m,new_n);
 274
 275   /* nothing was changed */
 276   if (new_m == A->m && new_n == A->n)
 277     return A;
 278
 279   old_m = A->m;	old_n = A->n;
 280   if ( new_m > A->max_m )
 281   {	/* re-allocate A->me */
 282      if (mem_info_is_on()) {
 283	 mem_bytes(TYPE_MAT,A->max_m*sizeof(Real *),
 284		      new_m*sizeof(Real *));
 285      }
 286
 287      A->me = RENEW(A->me,new_m,Real *);
 288      if ( ! A->me )
 289	error(E_MEM,"m_resize");
 290   }
 291   new_max_m = max(new_m,A->max_m);
 292   new_max_n = max(new_n,A->max_n);
 293   
 294#ifndef SEGMENTED
 295   new_size = new_max_m*new_max_n;
 296   if ( new_size > A->max_size )
 297   {	/* re-allocate A->base */
 298      if (mem_info_is_on()) {
 299	 mem_bytes(TYPE_MAT,A->max_m*A->max_n*sizeof(Real),
 300		      new_size*sizeof(Real));
 301      }
 302
 303      A->base = RENEW(A->base,new_size,Real);
 304      if ( ! A->base )
 305	error(E_MEM,"m_resize");
 306      A->max_size = new_size;
 307   }
 308   
 309   /* now set up A->me[i] */
 310   for ( i = 0; i < new_m; i++ )
 311     A->me[i] = &(A->base[i*new_n]);
 312   
 313   /* now shift data in matrix */
 314   if ( old_n > new_n )
 315   {
 316      for ( i = 1; i < min(old_m,new_m); i++ )
 317	MEM_COPY((char *)&(A->base[i*old_n]),
 318		 (char *)&(A->base[i*new_n]),
 319		 sizeof(Real)*new_n);
 320   }
 321   else if ( old_n < new_n )
 322   {
 323      for ( i = (int)(min(old_m,new_m))-1; i > 0; i-- )
 324      {   /* copy & then zero extra space */
 325	 MEM_COPY((char *)&(A->base[i*old_n]),
 326		  (char *)&(A->base[i*new_n]),
 327		  sizeof(Real)*old_n);
 328	 __zero__(&(A->base[i*new_n+old_n]),(new_n-old_n));
 329      }
 330      __zero__(&(A->base[old_n]),(new_n-old_n));
 331      A->max_n = new_n;
 332   }
 333   /* zero out the new rows.. */
 334   for ( i = old_m; i < new_m; i++ )
 335     __zero__(&(A->base[i*new_n]),new_n);
 336#else
 337   if ( A->max_n < new_n )
 338   {
 339      Real	*tmp;
 340      
 341      for ( i = 0; i < A->max_m; i++ )
 342      {
 343	 if (mem_info_is_on()) {
 344	    mem_bytes(TYPE_MAT,A->max_n*sizeof(Real),
 345			 new_max_n*sizeof(Real));
 346	 }	
 347
 348	 if ( (tmp = RENEW(A->me[i],new_max_n,Real)) == NULL )
 349	   error(E_MEM,"m_resize");
 350	 else {	
 351	    A->me[i] = tmp;
 352	 }
 353      }
 354      for ( i = A->max_m; i < new_max_m; i++ )
 355      {
 356	 if ( (tmp = NEW_A(new_max_n,Real)) == NULL )
 357	   error(E_MEM,"m_resize");
 358	 else {
 359	    A->me[i] = tmp;
 360
 361	    if (mem_info_is_on()) {
 362	       mem_bytes(TYPE_MAT,0,new_max_n*sizeof(Real));
 363	    }	    
 364	 }
 365      }
 366   }
 367   else if ( A->max_m < new_m )
 368   {
 369      for ( i = A->max_m; i < new_m; i++ ) 
 370	if ( (A->me[i] = NEW_A(new_max_n,Real)) == NULL )
 371	  error(E_MEM,"m_resize");
 372	else if (mem_info_is_on()) {
 373	   mem_bytes(TYPE_MAT,0,new_max_n*sizeof(Real));
 374	}
 375      
 376   }
 377   
 378   if ( old_n < new_n )
 379   {
 380      for ( i = 0; i < old_m; i++ )
 381	__zero__(&(A->me[i][old_n]),new_n-old_n);
 382   }
 383   
 384   /* zero out the new rows.. */
 385   for ( i = old_m; i < new_m; i++ )
 386     __zero__(A->me[i],new_n);
 387#endif
 388   
 389   A->max_m = new_max_m;
 390   A->max_n = new_max_n;
 391   A->max_size = A->max_m*A->max_n;
 392   A->m = new_m;	A->n = new_n;
 393   
 394   return A;
 395}
 396
 397/* px_resize -- returns the permutation px with size new_size
 398   -- px is set to the identity permutation */
 399PERM	*px_resize(px,new_size)
 400PERM	*px;
 401int	new_size;
 402{
 403   int	i;
 404   
 405   if (new_size < 0)
 406     error(E_NEG,"px_resize");
 407
 408   if ( ! px )
 409     return px_get(new_size);
 410   
 411   /* nothing is changed */
 412   if (new_size == px->size)
 413     return px;
 414
 415   if ( new_size > px->max_size )
 416   {
 417      if (mem_info_is_on()) {
 418	 mem_bytes(TYPE_PERM,px->max_size*sizeof(u_int),
 419		      new_size*sizeof(u_int));
 420      }
 421      px->pe = RENEW(px->pe,new_size,u_int);
 422      if ( ! px->pe )
 423	error(E_MEM,"px_resize");
 424      px->max_size = new_size;
 425   }
 426   if ( px->size <= new_size )
 427     /* extend permutation */
 428     for ( i = px->size; i < new_size; i++ )
 429       px->pe[i] = i;
 430   else
 431     for ( i = 0; i < new_size; i++ )
 432       px->pe[i] = i;
 433   
 434   px->size = new_size;
 435   
 436   return px;
 437}
 438
 439/* v_resize -- returns the vector x with dim new_dim
 440   -- x is set to the zero vector */
 441VEC	*v_resize(x,new_dim)
 442VEC	*x;
 443int	new_dim;
 444{
 445   
 446   if (new_dim < 0)
 447     error(E_NEG,"v_resize");
 448
 449   if ( ! x )
 450     return v_get(new_dim);
 451
 452   /* nothing is changed */
 453   if (new_dim == x->dim)
 454     return x;
 455
 456   if ( x->max_dim == 0 )	/* assume that it's from sub_vec */
 457     return v_get(new_dim);
 458   
 459   if ( new_dim > x->max_dim )
 460   {
 461      if (mem_info_is_on()) { 
 462	 mem_bytes(TYPE_VEC,x->max_dim*sizeof(Real),
 463			 new_dim*sizeof(Real));
 464      }
 465
 466      x->ve = RENEW(x->ve,new_dim,Real);
 467      if ( ! x->ve )
 468	error(E_MEM,"v_resize");
 469      x->max_dim = new_dim;
 470   }
 471   
 472   if ( new_dim > x->dim )
 473     __zero__(&(x->ve[x->dim]),new_dim - x->dim);
 474   x->dim = new_dim;
 475   
 476   return x;
 477}
 478
 479
 480
 481
 482/* Varying number of arguments */
 483/* other functions of this type are in sparse.c and zmemory.c */
 484
 485
 486
 487#ifdef ANSI_C
 488
 489
 490/* To allocate memory to many arguments. 
 491   The function should be called:
 492   v_get_vars(dim,&x,&y,&z,...,NULL);
 493   where 
 494     int dim;
 495     VEC *x, *y, *z,...;
 496     The last argument should be NULL ! 
 497     dim is the length of vectors x,y,z,...
 498     returned value is equal to the number of allocated variables
 499     Other gec_... functions are similar.
 500*/
 501
 502int v_get_vars(int dim,...) 
 503{
 504   va_list ap;
 505   int i=0;
 506   VEC **par;
 507   
 508   va_start(ap, dim);
 509   while (par = va_arg(ap,VEC **)) {   /* NULL ends the list*/
 510      *par = v_get(dim);
 511      i++;
 512   } 
 513
 514   va_end(ap);
 515   return i;
 516}
 517
 518
 519int iv_get_vars(int dim,...) 
 520{
 521   va_list ap;
 522   int i=0;
 523   IVEC **par;
 524   
 525   va_start(ap, dim);
 526   while (par = va_arg(ap,IVEC **)) {   /* NULL ends the list*/
 527      *par = iv_get(dim);
 528      i++;
 529   } 
 530
 531   va_end(ap);
 532   return i;
 533}
 534
 535int m_get_vars(int m,int n,...) 
 536{
 537   va_list ap;
 538   int i=0;
 539   MAT **par;
 540   
 541   va_start(ap, n);
 542   while (par = va_arg(ap,MAT **)) {   /* NULL ends the list*/
 543      *par = m_get(m,n);
 544      i++;
 545   } 
 546
 547   va_end(ap);
 548   return i;
 549}
 550
 551int px_get_vars(int dim,...) 
 552{
 553   va_list ap;
 554   int i=0;
 555   PERM **par;
 556   
 557   va_start(ap, dim);
 558   while (par = va_arg(ap,PERM **)) {   /* NULL ends the list*/
 559      *par = px_get(dim);
 560      i++;
 561   } 
 562
 563   va_end(ap);
 564   return i;
 565}
 566
 567
 568
 569/* To resize memory for many arguments. 
 570   The function should be called:
 571   v_resize_vars(new_dim,&x,&y,&z,...,NULL);
 572   where 
 573     int new_dim;
 574     VEC *x, *y, *z,...;
 575     The last argument should be NULL ! 
 576     rdim is the resized length of vectors x,y,z,...
 577     returned value is equal to the number of allocated variables.
 578     If one of x,y,z,.. arguments is NULL then memory is allocated to this 
 579     argument. 
 580     Other *_resize_list() functions are similar.
 581*/
 582
 583int v_resize_vars(int new_dim,...)
 584{
 585   va_list ap;
 586   int i=0;
 587   VEC **par;
 588   
 589   va_start(ap, new_dim);
 590   while (par = va_arg(ap,VEC **)) {   /* NULL ends the list*/
 591      *par = v_resize(*par,new_dim);
 592      i++;
 593   } 
 594
 595   va_end(ap);
 596   return i;
 597}
 598
 599
 600
 601int iv_resize_vars(int new_dim,...) 
 602{
 603   va_list ap;
 604   int i=0;
 605   IVEC **par;
 606   
 607   va_start(ap, new_dim);
 608   while (par = va_arg(ap,IVEC **)) {   /* NULL ends the list*/
 609      *par = iv_resize(*par,new_dim);
 610      i++;
 611   } 
 612
 613   va_end(ap);
 614   return i;
 615}
 616
 617int m_resize_vars(int m,int n,...) 
 618{
 619   va_list ap;
 620   int i=0;
 621   MAT **par;
 622   
 623   va_start(ap, n);
 624   while (par = va_arg(ap,MAT **)) {   /* NULL ends the list*/
 625      *par = m_resize(*par,m,n);
 626      i++;
 627   } 
 628
 629   va_end(ap);
 630   return i;
 631}
 632
 633
 634int px_resize_vars(int new_dim,...) 
 635{
 636   va_list ap;
 637   int i=0;
 638   PERM **par;
 639   
 640   va_start(ap, new_dim);
 641   while (par = va_arg(ap,PERM **)) {   /* NULL ends the list*/
 642      *par = px_resize(*par,new_dim);
 643      i++;
 644   } 
 645
 646   va_end(ap);
 647   return i;
 648}
 649
 650/* To deallocate memory for many arguments. 
 651   The function should be called:
 652   v_free_vars(&x,&y,&z,...,NULL);
 653   where 
 654     VEC *x, *y, *z,...;
 655     The last argument should be NULL ! 
 656     There must be at least one not NULL argument.
 657     returned value is equal to the number of allocated variables.
 658     Returned value of x,y,z,.. is VNULL.
 659     Other *_free_list() functions are similar.
 660*/
 661
 662
 663int v_free_vars(VEC **pv,...)
 664{
 665   va_list ap;
 666   int i=1;
 667   VEC **par;
 668   
 669   v_free(*pv);
 670   *pv = VNULL;
 671   va_start(ap, pv);
 672   while (par = va_arg(ap,VEC **)) {   /* NULL ends the list*/
 673      v_free(*par); 
 674      *par = VNULL;
 675      i++;
 676   } 
 677
 678   va_end(ap);
 679   return i;
 680}
 681
 682
 683int iv_free_vars(IVEC **ipv,...)
 684{
 685   va_list ap;
 686   int i=1;
 687   IVEC **par;
 688   
 689   iv_free(*ipv);
 690   *ipv = IVNULL;
 691   va_start(ap, ipv);
 692   while (par = va_arg(ap,IVEC **)) {   /* NULL ends the list*/
 693      iv_free(*par); 
 694      *par = IVNULL;
 695      i++;
 696   } 
 697
 698   va_end(ap);
 699   return i;
 700}
 701
 702
 703int px_free_vars(PERM **vpx,...)
 704{
 705   va_list ap;
 706   int i=1;
 707   PERM **par;
 708   
 709   px_free(*vpx);
 710   *vpx = PNULL;
 711   va_start(ap, vpx);
 712   while (par = va_arg(ap,PERM **)) {   /* NULL ends the list*/
 713      px_free(*par); 
 714      *par = PNULL;
 715      i++;
 716   } 
 717
 718   va_end(ap);
 719   return i;
 720}
 721
 722int m_free_vars(MAT **va,...)
 723{
 724   va_list ap;
 725   int i=1;
 726   MAT **par;
 727   
 728   m_free(*va);
 729   *va = MNULL;
 730   va_start(ap, va);
 731   while (par = va_arg(ap,MAT **)) {   /* NULL ends the list*/
 732      m_free(*par); 
 733      *par = MNULL;
 734      i++;
 735   } 
 736
 737   va_end(ap);
 738   return i;
 739}
 740
 741
 742#elif VARARGS
 743/* old varargs is used */
 744
 745
 746
 747/* To allocate memory to many arguments. 
 748   The function should be called:
 749   v_get_vars(dim,&x,&y,&z,...,VNULL);
 750   where 
 751     int dim;
 752     VEC *x, *y, *z,...;
 753     The last argument should be VNULL ! 
 754     dim is the length of vectors x,y,z,...
 755*/
 756
 757int v_get_vars(va_alist) va_dcl
 758{
 759   va_list ap;
 760   int dim,i=0;
 761   VEC **par;
 762   
 763   va_start(ap);
 764   dim = va_arg(ap,int);
 765   while (par = va_arg(ap,VEC **)) {   /* NULL ends the list*/
 766      *par = v_get(dim);
 767      i++;
 768   } 
 769
 770   va_end(ap);
 771   return i;
 772}
 773
 774
 775int iv_get_vars(va_alist) va_dcl
 776{
 777   va_list ap;
 778   int i=0, dim;
 779   IVEC **par;
 780   
 781   va_start(ap);
 782   dim = va_arg(ap,int);
 783   while (par = va_arg(ap,IVEC **)) {   /* NULL ends the list*/
 784      *par = iv_get(dim);
 785      i++;
 786   } 
 787
 788   va_end(ap);
 789   return i;
 790}
 791
 792int m_get_vars(va_alist) va_dcl
 793{
 794   va_list ap;
 795   int i=0, n, m;
 796   MAT **par;
 797   
 798   va_start(ap);
 799   m = va_arg(ap,int);
 800   n = va_arg(ap,int);
 801   while (par = va_arg(ap,MAT **)) {   /* NULL ends the list*/
 802      *par = m_get(m,n);
 803      i++;
 804   } 
 805
 806   va_end(ap);
 807   return i;
 808}
 809
 810
 811
 812int px_get_vars(va_alist) va_dcl
 813{
 814   va_list ap;
 815   int i=0, dim;
 816   PERM **par;
 817   
 818   va_start(ap);
 819   dim = va_arg(ap,int);
 820   while (par = va_arg(ap,PERM **)) {   /* NULL ends the list*/
 821      *par = px_get(dim);
 822      i++;
 823   } 
 824
 825   va_end(ap);
 826   return i;
 827}
 828
 829
 830
 831/* To resize memory for many arguments. 
 832   The function should be called:
 833   v_resize_vars(new_dim,&x,&y,&z,...,NULL);
 834   where 
 835     int new_dim;
 836     VEC *x, *y, *z,...;
 837     The last argument should be NULL ! 
 838     rdim is the resized length of vectors x,y,z,...
 839     returned value is equal to the number of allocated variables.
 840     If one of x,y,z,.. arguments is NULL then memory is allocated to this 
 841     argument. 
 842     Other *_resize_list() functions are similar.
 843*/
 844
 845int v_resize_vars(va_alist) va_dcl
 846{
 847   va_list ap;
 848   int i=0, new_dim;
 849   VEC **par;
 850   
 851   va_start(ap);
 852   new_dim = va_arg(ap,int);
 853   while (par = va_arg(ap,VEC **)) {   /* NULL ends the list*/
 854      *par = v_resize(*par,new_dim);
 855      i++;
 856   } 
 857
 858   va_end(ap);
 859   return i;
 860}
 861
 862
 863
 864int iv_resize_vars(va_alist) va_dcl
 865{
 866   va_list ap;
 867   int i=0, new_dim;
 868   IVEC **par;
 869   
 870   va_start(ap);
 871   new_dim = va_arg(ap,int);
 872   while (par = va_arg(ap,IVEC **)) {   /* NULL ends the list*/
 873      *par = iv_resize(*par,new_dim);
 874      i++;
 875   } 
 876
 877   va_end(ap);
 878   return i;
 879}
 880
 881int m_resize_vars(va_alist) va_dcl
 882{
 883   va_list ap;
 884   int i=0, m, n;
 885   MAT **par;
 886   
 887   va_start(ap);
 888   m = va_arg(ap,int);
 889   n = va_arg(ap,int);
 890   while (par = va_arg(ap,MAT **)) {   /* NULL ends the list*/
 891      *par = m_resize(*par,m,n);
 892      i++;
 893   } 
 894
 895   va_end(ap);
 896   return i;
 897}
 898
 899int px_resize_vars(va_alist) va_dcl
 900{
 901   va_list ap;
 902   int i=0, new_dim;
 903   PERM **par;
 904   
 905   va_start(ap);
 906   new_dim = va_arg(ap,int);
 907   while (par = va_arg(ap,PERM **)) {   /* NULL ends the list*/
 908      *par = px_resize(*par,new_dim);
 909      i++;
 910   } 
 911
 912   va_end(ap);
 913   return i;
 914}
 915
 916
 917/* To deallocate memory for many arguments. 
 918   The function should be called:
 919   v_free_vars(&x,&y,&z,...,NULL);
 920   where 
 921     VEC *x, *y, *z,...;
 922     The last argument should be NULL ! 
 923     returned value is equal to the number of allocated variables.
 924     Returned value of x,y,z,.. is VNULL.
 925     Other *_free_list() functions are similar.
 926*/
 927
 928
 929int v_free_vars(va_alist) va_dcl
 930{
 931   va_list ap;
 932   int i=0;
 933   VEC **par;
 934   
 935   va_start(ap);
 936   while (par = va_arg(ap,VEC **)) {   /* NULL ends the list*/
 937      v_free(*par); 
 938      *par = VNULL;
 939      i++;
 940   } 
 941
 942   va_end(ap);
 943   return i;
 944}
 945
 946
 947
 948int iv_free_vars(va_alist) va_dcl
 949{
 950   va_list ap;
 951   int i=0;
 952   IVEC **par;
 953   
 954   va_start(ap);
 955   while (par = va_arg(ap,IVEC **)) {   /* NULL ends the list*/
 956      iv_free(*par); 
 957      *par = IVNULL;
 958      i++;
 959   } 
 960
 961   va_end(ap);
 962   return i;
 963}
 964
 965
 966int px_free_vars(va_alist) va_dcl
 967{
 968   va_list ap;
 969   int i=0;
 970   PERM **par;
 971   
 972   va_start(ap);
 973   while (par = va_arg(ap,PERM **)) {   /* NULL ends the list*/
 974      px_free(*par); 
 975      *par = PNULL;
 976      i++;
 977   } 
 978
 979   va_end(ap);
 980   return i;
 981}
 982
 983int m_free_vars(va_alist) va_dcl
 984{
 985   va_list ap;
 986   int i=0;
 987   MAT **par;
 988   
 989   va_start(ap);
 990   while (par = va_arg(ap,MAT **)) {   /* NULL ends the list*/
 991      m_free(*par); 
 992      *par = MNULL;
 993      i++;
 994   } 
 995
 996   va_end(ap);
 997   return i;
 998}
 999
1000
1001
1002#endif /* VARARGS */
1003  
1004