PageRenderTime 45ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/src/mesch/memory.c

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