home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume28 / mvalloc / part01 next >
Text File  |  1992-02-23  |  36KB  |  1,208 lines

  1. Newsgroups: comp.sources.misc
  2. From: thewalt@canuck.ce.berkeley.edu (Chris Thewalt)
  3. Subject:  v28i072:  mvalloc - matrix/vector allocator in C, Part01/01
  4. Message-ID: <1992Feb24.045022.18270@sparky.imd.sterling.com>
  5. X-Md4-Signature: d86f4138ede62053d534c06bb584feb7
  6. Date: Mon, 24 Feb 1992 04:50:22 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: thewalt@canuck.ce.berkeley.edu (Chris Thewalt)
  10. Posting-number: Volume 28, Issue 72
  11. Archive-name: mvalloc/part01
  12. Environment: UNIX, MSDOS, MSC
  13.  
  14. Well, I finally got fed up writing allocators to make an array of
  15. ints or a matrix of doubles, so I sat down and wrote a generic
  16. allocator.  The single function MValloc(), included in the shar file below,
  17. allocates n-dimensional arrays (1 for vector, 2 for matrix, 3 or more
  18. if you need them...) with different element types.  The supported
  19. element types are char, short, int, long, float, double, void *
  20. (the unsigned/signed variants of integral types are also supported). The
  21. returned object can be indexed like a normal array, using as many
  22. indices as necessary for the dimension requested. The MValloc function
  23. also hides information about the array that can be recovered later
  24. with MV query functions.  See the files README and Interface for more
  25. details. 
  26.  
  27. Uses either ANSI or old C, and should work on any system. It has
  28. been run on DECstations, Sun Sparcs, Silicon Graphics Irises, and
  29. PC's using MSC.
  30.  
  31. Chris Thewalt
  32. --------------
  33. #! /bin/sh
  34. # This is a shell archive.  Remove anything before this line, then feed it
  35. # into a shell via "sh file" or similar.  To overwrite existing files,
  36. # type "sh file -c".
  37. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  38. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  39. # Contents:  README Interface Makefile mvalloc.c mvalloc.h test1.c
  40. #   test2.c test3.c test4.c test5.c
  41. # Wrapped by kent@sparky on Sun Feb 23 22:46:30 1992
  42. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  43. echo If this archive is complete, you will see the following message:
  44. echo '          "shar: End of archive 1 (of 1)."'
  45. if test -f 'README' -a "${1}" != "-c" ; then 
  46.   echo shar: Will not clobber existing file \"'README'\"
  47. else
  48.   echo shar: Extracting \"'README'\" \(1686 characters\)
  49.   sed "s/^X//" >'README' <<'END_OF_FILE'
  50. X    The MValloc package is a set of C functions to allocate general
  51. Xn-dimensional matrices (n==1 gives an array).  The code is written to run
  52. Xunder ANSI or classic C compilers.  The vector/matrix elements
  53. Xcan be:
  54. X
  55. X char, short, int, long (or signed/unsigned variants)
  56. X float, double
  57. X void *
  58. X
  59. X    The function MValloc returns a void * that can be assigned directly to
  60. Xa  pointer of the desired type (eg. double *** for a 3-d double matrix).
  61. XThe resulting pointer can then be subscripted like a normal C matrix.
  62. XAll the edge pointer spaghetti is done by MValloc to make this work, and in
  63. Xthe larger dimensional cases there are a lot of pointers... 
  64. XIn addition to initiating the pointers, MValloc hides information about
  65. Xthe matrix that can be returned from other MV query functions, as shown
  66. Xint mvalloc.h and described in the file called Interface.
  67. X
  68. X    The MValloc package rigorously treats the base pointers to objects
  69. Xdifferently (eg. char * and double * may have different size and
  70. Xrepresentation), and makes no assumptions at all for 1, 2 and 3-d matrices.
  71. XHowever, in order to make n-dimensional allocation possible, I make the
  72. Xfairly portable assumption that for any given base object, say double, 
  73. Xthe deeper pointer levels (double **, double ***, ...) all have the same
  74. Xsize and representation.  This has proven to be valid on many systems,
  75. Xincluding DECstations, Sun Sparc,  Silicon Graphics Iris, PC with MSC
  76. Xcompiler.  If it doesn't work on your system I'd be interested to hear
  77. Xabout it, but remember, you get what you pay for :-).
  78. X
  79. X    The functions test1.c through test5.c are examples of how to use the
  80. Xpacakage for dimensions 1, 2, 3, 4 and 5.
  81. X
  82. XChris Thewalt (2/16/92)
  83. END_OF_FILE
  84.   if test 1686 -ne `wc -c <'README'`; then
  85.     echo shar: \"'README'\" unpacked with wrong size!
  86.   fi
  87.   # end of 'README'
  88. fi
  89. if test -f 'Interface' -a "${1}" != "-c" ; then 
  90.   echo shar: Will not clobber existing file \"'Interface'\"
  91. else
  92.   echo shar: Extracting \"'Interface'\" \(2955 characters\)
  93.   sed "s/^X//" >'Interface' <<'END_OF_FILE'
  94. XThis file describes the programming interface to the MValloc package. When
  95. Xusing non-ANSI compilers that don't use funcion prototypes pay special 
  96. Xattention to the DANGER note below.
  97. X
  98. X
  99. X*** The supported element types are:
  100. X
  101. XMV_CHAR, MV_SHORT, MV_INT, MV_LONG, MV_FLOAT, MV_DOUBLE, MV_VOIDP
  102. X
  103. XOne can get a signed/unsigned variant of the integral types my assigning the
  104. Xpointer returned from MValloc to the correct pointer type (see example
  105. Xbelow).
  106. X
  107. X*** The function call interface is:
  108. X
  109. Xvoid *MValloc(int eltype, int dimension, ...)
  110. X
  111. X      The MValloc function returns a void pointer that represents the
  112. X      starting location of the n-dimensional matrix requested (or NULL 
  113. X      on error). The first argument is one of the supported element types 
  114. X      (listed above), the second argument is the number of dimensions 
  115. X      for this object (1 for vector, 2 for matrix, 3 or larger for higher 
  116. X      dimensional objects).  The remaining arguments are the sizes of 
  117. X      each of the dimensions, supplied as long ints. For example:
  118. X
  119. X      short          *short_array  = MValloc(MV_SHORT, 1, 200L);
  120. X      unsigned short *ushort_array = MValloc(MV_SHORT, 1, 200L);
  121. X      double        **matrix       = MValloc(MV_DOUBLE, 2, 100L, 100L);
  122. X      int        *****hyper        = MValloc(MV_INT, 5, 3L, 3L, 3L, 3L, 3L);
  123. X
  124. Xvoid  MVfree(void *mvobj)
  125. X
  126. X      The MVfree function checks to make sure the pointer given represents
  127. X      an MVobject, and if so, MVfree free's all memory associated with the
  128. X      object. 
  129. X
  130. Xint   MVdimension(void *mvobj)
  131. X
  132. X      The MVdimension function checks to make sure the pointer given 
  133. X      represents an MVobject, and if so, MVdimension returns the number
  134. X      of dimensions in the specified object.  Returns -1 on error.
  135. X
  136. Xlong  MVsize(void *mvobj, int dimension)
  137. X
  138. X      The MVsize function checks to make sure the pointer given 
  139. X      represents an MVobject, and if so, MVsize returns the size of 
  140. X      the specified dimension (0 based), or -1 on error.  For example, 
  141. X      given the 2-dimensional double matrix allocated above we could say:
  142. X
  143. X      int rows = MVsize(matrix, 0);
  144. X      int cols = MVsize(matrix, 1);
  145. X
  146. Xint   MVtype(void *mvobj)
  147. X
  148. X      The MVtype function checks to make sure the pointer given 
  149. X      represents an MVobject, and if so, MVtype returns the number
  150. X      associated with the element type (eg. MV_CHAR).  Returns -1 on error.
  151. X
  152. X************************ DANGER *******************************************
  153. X
  154. XWhen on a non-ANSI compiler that does not use the function prototypes given
  155. Xin mvalloc.h, the programmer must be careful to cast the arguments of all
  156. Xmvalloc functions to the correct types.  In particular, the free and query
  157. Xfunctions require a void *mvobj and this should be explicity cast by the
  158. Xprogrammer (things like double * may have a different representation).
  159. XAlso, the sizes given in MValloc() should all be long ints, which was
  160. Xnecessary to make this package usefull in the 16 bit world.
  161. END_OF_FILE
  162.   if test 2955 -ne `wc -c <'Interface'`; then
  163.     echo shar: \"'Interface'\" unpacked with wrong size!
  164.   fi
  165.   # end of 'Interface'
  166. fi
  167. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  168.   echo shar: Will not clobber existing file \"'Makefile'\"
  169. else
  170.   echo shar: Extracting \"'Makefile'\" \(588 characters\)
  171.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  172. XCFLAGS  = 
  173. XLDFLAGS =
  174. X
  175. Xall: test1 test2 test3 test4 test5
  176. X
  177. Xtest1: test1.o mvalloc.o
  178. X    $(CC) $(LDFLAGS) -o test1  mvalloc.o test1.o
  179. X
  180. Xtest2: test2.o mvalloc.o
  181. X    $(CC) $(LDFLAGS) -o test2  mvalloc.o test2.o
  182. X
  183. Xtest3: test3.o mvalloc.o
  184. X    $(CC) $(LDFLAGS) -o test3  mvalloc.o test3.o
  185. X
  186. Xtest4: test4.o mvalloc.o
  187. X    $(CC) $(LDFLAGS) -o test4  mvalloc.o test4.o
  188. X
  189. Xtest5: test5.o mvalloc.o
  190. X    $(CC) $(LDFLAGS) -o test5  mvalloc.o test5.o
  191. X
  192. Xclean:
  193. X    /bin/rm -f *.o test1 test2 test3 test4 test5
  194. X
  195. Xtest1.o: mvalloc.h
  196. Xtest2.o: mvalloc.h
  197. Xtest3.o: mvalloc.h
  198. Xtest4.o: mvalloc.h
  199. Xtest5.o: mvalloc.h
  200. Xmvalloc.o: mvalloc.h
  201. END_OF_FILE
  202.   if test 588 -ne `wc -c <'Makefile'`; then
  203.     echo shar: \"'Makefile'\" unpacked with wrong size!
  204.   fi
  205.   # end of 'Makefile'
  206. fi
  207. if test -f 'mvalloc.c' -a "${1}" != "-c" ; then 
  208.   echo shar: Will not clobber existing file \"'mvalloc.c'\"
  209. else
  210.   echo shar: Extracting \"'mvalloc.c'\" \(16034 characters\)
  211.   sed "s/^X//" >'mvalloc.c' <<'END_OF_FILE'
  212. X#ifndef lint
  213. Xstatic char     rcsid[] =
  214. X"$Id: mvalloc.c,v 1.2 1992/02/16 19:23:04 thewalt Exp thewalt $";
  215. Xstatic char    *copyright = "Copyright (C) 1991, 1992, Chris Thewalt";
  216. X#endif
  217. X
  218. X/*
  219. X * Copyright (C) 1991, 1992 by Chris Thewalt (thewalt@ce.berkeley.edu)
  220. X *
  221. X * Permission to use, copy, modify, and distribute this software 
  222. X * for any purpose and without fee is hereby granted, provided
  223. X * that the above copyright notices appear in all copies and that both the
  224. X * copyright notice and this permission notice appear in supporting
  225. X * documentation.  This software is provided "as is" without express or
  226. X * implied warranty.
  227. X */
  228. X
  229. X#include <stdio.h>
  230. X#ifdef __STDC__
  231. X#include <stddef.h>
  232. X#include <stdlib.h>
  233. X#include <stdarg.h>
  234. X#else  /* not __STDC__ */
  235. X#include <varargs.h>
  236. Xextern void *malloc();
  237. Xextern void  free();
  238. Xextern void  exit();
  239. X#endif /* not __STDC__ */
  240. X#include "mvalloc.h"
  241. X
  242. Xtypedef double  Align;
  243. Xtypedef void   *VoidPtr;
  244. X
  245. Xtypedef struct {
  246. X    int             magic;
  247. X    int             eltype;
  248. X    int             dimension;
  249. X    long           *size;
  250. X    Align           start;
  251. X} MVobj;
  252. X
  253. X#define  MV_MAGIC 2099
  254. X
  255. Xstatic MVobj      offset_var;
  256. X#define MV_OFFSET ((char*)&offset_var.start-(char*)&offset_var)
  257. X
  258. Xstatic void *
  259. XMallocOrDie(size)
  260. Xlong size;
  261. X{
  262. X    void           *p;
  263. X    extern void    *malloc();
  264. X
  265. X    if ((p = malloc(size)) == NULL) {
  266. X    fprintf(stderr, "MallocOrDie: insufficient memory\n");
  267. X    exit(1);
  268. X    }
  269. X    return p;
  270. X}
  271. X
  272. X#ifdef __STDC__
  273. Xvoid *
  274. XMValloc(int eltype, int dimension, ...)
  275. X#else  /* not __STDC__ */
  276. Xvoid *
  277. XMValloc(va_alist)
  278. Xva_dcl
  279. X#endif /* not __STDC__ */
  280. X{
  281. X    va_list         ap;
  282. X    MVobj          *mvp;
  283. X    char     ***c3, **c2;
  284. X    short        ***s3, **s2;
  285. X    int          ***i3, **i2;
  286. X    long         ***l3, **l2;
  287. X    float        ***f3, **f2;
  288. X    double       ***d3, **d2;
  289. X    VoidPtr      ***v3, **v2;
  290. X    void           *retval = 0;
  291. X    long            i, j, *size;
  292. X    long            pp_count, p_count, el_count;
  293. X    long            base, count;
  294. X#ifndef __STDC__
  295. X    int             eltype, dimension;
  296. X#endif
  297. X
  298. X#ifdef __STDC__
  299. X    va_start(ap, dimension);
  300. X#else  /* not __STDC__ */
  301. X    va_start(ap);
  302. X    eltype = va_arg(ap, int);
  303. X    dimension = va_arg(ap, int);
  304. X#endif /* not __STDC__ */
  305. X    el_count = 1;
  306. X    if (dimension > 0) {
  307. X        size = MallocOrDie((long) dimension * sizeof(long));
  308. X    for (i=0; i < dimension; i++) {
  309. X        size[i] = va_arg(ap, long);
  310. X        if (size[i] < 0) {
  311. X            fprintf(stderr, "MValloc: negative size request\n");
  312. X        return 0;
  313. X        }
  314. X        el_count *= size[i];
  315. X    }
  316. X    } else {
  317. X    fprintf(stderr, "MValloc: non-positive dimension argument\n");
  318. X    return 0;
  319. X    }
  320. X    va_end(ap);
  321. X    if (dimension == 1) {
  322. X    p_count = pp_count = 0;
  323. X    } else if (dimension == 2) {
  324. X    p_count = el_count / size[dimension-1];
  325. X    pp_count = 0;
  326. X    } else {
  327. X    pp_count = 0;
  328. X    p_count = 1;
  329. X    for (i = 0; i < dimension - 2; i++) {
  330. X        p_count *= size[i];
  331. X        pp_count += p_count;
  332. X    }
  333. X    p_count = el_count / size[dimension-1];
  334. X    }
  335. X    base = 0;
  336. X    count = 1;
  337. X    switch (eltype) {
  338. X      case MV_CHAR:
  339. X    if (dimension > 2 ) {
  340. X        mvp = MallocOrDie((long) MV_OFFSET + pp_count * sizeof(char **));
  341. X        retval = c3 = (char ***)((char *)mvp + MV_OFFSET);
  342. X        for (i = 0; i < dimension - 3; i++) {
  343. X            count *= size[i];
  344. X            for (j = 0; j < count; j++) {
  345. X            c3[base+j] = (char **)(c3 + base + count + j * size[i+1]);
  346. X            }
  347. X                base += count;
  348. X        }
  349. X        c3[base] = MallocOrDie((long) p_count * sizeof(char *));
  350. X        count *= size[dimension-3];
  351. X        for (i = 1; i < count; i++) 
  352. X        c3[base+i] = c3[base+i-1] + size[dimension-2];
  353. X        c3[base][0] = MallocOrDie((long) el_count * sizeof(char));
  354. X        for (i = 1; i < p_count; i++)
  355. X            c3[base][i] = c3[base][i-1] + size[dimension-1];
  356. X    } else if (dimension == 2) {
  357. X        mvp = MallocOrDie((long) MV_OFFSET + p_count * sizeof(char *));
  358. X        retval = c2 = (char **)((char *)mvp + MV_OFFSET);
  359. X        c2[0] = MallocOrDie((long) el_count * sizeof(char));
  360. X        for (i = 1; i < p_count; i++)
  361. X            c2[i] = c2[i-1] + size[1];
  362. X    } else {
  363. X        mvp = MallocOrDie((long) MV_OFFSET + el_count * sizeof(char));
  364. X        retval = (char *)((char *)mvp + MV_OFFSET);
  365. X    }
  366. X    break;
  367. X      case MV_SHORT:
  368. X    if (dimension > 2 ) {
  369. X        mvp = MallocOrDie((long) MV_OFFSET + pp_count * sizeof(short **));
  370. X        retval = s3 = (short ***)((char *)mvp + MV_OFFSET);
  371. X        for (i = 0; i < dimension - 3; i++) {
  372. X            count *= size[i];
  373. X            for (j = 0; j < count; j++) {
  374. X            s3[base+j] = (short **)(s3 + base + count + j * size[i+1]);
  375. X            }
  376. X                base += count;
  377. X        }
  378. X        s3[base] = MallocOrDie((long) p_count * sizeof(short *));
  379. X        count *= size[dimension-3];
  380. X        for (i = 1; i < count; i++) 
  381. X        s3[base+i] = s3[base+i-1] + size[dimension-2];
  382. X        s3[base][0] = MallocOrDie((long) el_count * sizeof(short));
  383. X        for (i = 1; i < p_count; i++)
  384. X            s3[base][i] = s3[base][i-1] + size[dimension-1];
  385. X    } else if (dimension == 2) {
  386. X        mvp = MallocOrDie((long) MV_OFFSET + p_count * sizeof(short *));
  387. X        retval = s2 = (short **)((char *)mvp + MV_OFFSET);
  388. X        s2[0] = MallocOrDie((long) el_count * sizeof(short));
  389. X        for (i = 1; i < p_count; i++)
  390. X            s2[i] = s2[i-1] + size[1];
  391. X    } else {
  392. X        mvp = MallocOrDie((long) MV_OFFSET + el_count * sizeof(short));
  393. X        retval = (short *)((char *)mvp + MV_OFFSET);
  394. X    }
  395. X    break;
  396. X      case MV_INT:
  397. X    if (dimension > 2 ) {
  398. X        mvp = MallocOrDie((long) MV_OFFSET + pp_count * sizeof(int **));
  399. X        retval = i3 = (int ***)((char *)mvp + MV_OFFSET);
  400. X        for (i = 0; i < dimension - 3; i++) {
  401. X            count *= size[i];
  402. X            for (j = 0; j < count; j++) {
  403. X            i3[base+j] = (int **)(i3 + base + count + j * size[i+1]);
  404. X            }
  405. X                base += count;
  406. X        }
  407. X        i3[base] = MallocOrDie((long) p_count * sizeof(int *));
  408. X        count *= size[dimension-3];
  409. X        for (i = 1; i < count; i++) 
  410. X        i3[base+i] = i3[base+i-1] + size[dimension-2];
  411. X        i3[base][0] = MallocOrDie((long) el_count * sizeof(int));
  412. X        for (i = 1; i < p_count; i++)
  413. X            i3[base][i] = i3[base][i-1] + size[dimension-1];
  414. X    } else if (dimension == 2) {
  415. X        mvp = MallocOrDie((long) MV_OFFSET + p_count * sizeof(int *));
  416. X        retval = i2 = (int **)((char *)mvp + MV_OFFSET);
  417. X        i2[0] = MallocOrDie((long) el_count * sizeof(int));
  418. X        for (i = 1; i < p_count; i++)
  419. X            i2[i] = i2[i-1] + size[1];
  420. X    } else {
  421. X        mvp = MallocOrDie((long) MV_OFFSET + el_count * sizeof(int));
  422. X        retval = (int *)((char *)mvp + MV_OFFSET);
  423. X    }
  424. X    break;
  425. X      case MV_LONG:
  426. X    if (dimension > 2 ) {
  427. X        mvp = MallocOrDie((long) MV_OFFSET + pp_count * sizeof(long **));
  428. X        retval = l3 = (long ***)((char *)mvp + MV_OFFSET);
  429. X        for (i = 0; i < dimension - 3; i++) {
  430. X            count *= size[i];
  431. X            for (j = 0; j < count; j++) {
  432. X            l3[base+j] = (long **)(l3 + base + count + j * size[i+1]);
  433. X            }
  434. X                base += count;
  435. X        }
  436. X        l3[base] = MallocOrDie((long) p_count * sizeof(long *));
  437. X        count *= size[dimension-3];
  438. X        for (i = 1; i < count; i++) 
  439. X        l3[base+i] = l3[base+i-1] + size[dimension-2];
  440. X        l3[base][0] = MallocOrDie((long) el_count * sizeof(long));
  441. X        for (i = 1; i < p_count; i++)
  442. X            l3[base][i] = l3[base][i-1] + size[dimension-1];
  443. X    } else if (dimension == 2) {
  444. X        mvp = MallocOrDie((long) MV_OFFSET + p_count * sizeof(long *));
  445. X        retval = l2 = (long **)((char *)mvp + MV_OFFSET);
  446. X        l2[0] = MallocOrDie((long) el_count * sizeof(long));
  447. X        for (i = 1; i < p_count; i++)
  448. X            l2[i] = l2[i-1] + size[1];
  449. X    } else {
  450. X        mvp = MallocOrDie((long) MV_OFFSET + el_count * sizeof(long));
  451. X        retval = (long *)((char *)mvp + MV_OFFSET);
  452. X    }
  453. X    break;
  454. X      case MV_FLOAT:
  455. X    if (dimension > 2 ) {
  456. X        mvp = MallocOrDie((long) MV_OFFSET + pp_count * sizeof(float **));
  457. X        retval = f3 = (float ***)((char *)mvp + MV_OFFSET);
  458. X        for (i = 0; i < dimension - 3; i++) {
  459. X            count *= size[i];
  460. X            for (j = 0; j < count; j++) {
  461. X            f3[base+j] = (float **)(f3 + base + count + j * size[i+1]);
  462. X            }
  463. X                base += count;
  464. X        }
  465. X        f3[base] = MallocOrDie((long) p_count * sizeof(float *));
  466. X        count *= size[dimension-3];
  467. X        for (i = 1; i < count; i++) 
  468. X        f3[base+i] = f3[base+i-1] + size[dimension-2];
  469. X        f3[base][0] = MallocOrDie((long) el_count * sizeof(float));
  470. X        for (i = 1; i < p_count; i++)
  471. X            f3[base][i] = f3[base][i-1] + size[dimension-1];
  472. X    } else if (dimension == 2) {
  473. X        mvp = MallocOrDie((long) MV_OFFSET + p_count * sizeof(float *));
  474. X        retval = f2 = (float **)((char *)mvp + MV_OFFSET);
  475. X        f2[0] = MallocOrDie((long) el_count * sizeof(float));
  476. X        for (i = 1; i < p_count; i++)
  477. X            f2[i] = f2[i-1] + size[1];
  478. X    } else {
  479. X        mvp = MallocOrDie((long) MV_OFFSET + el_count * sizeof(float));
  480. X        retval = (float *)((char *)mvp + MV_OFFSET);
  481. X    }
  482. X    break;
  483. X      case MV_DOUBLE:
  484. X    if (dimension > 2 ) {
  485. X        mvp = MallocOrDie((long) MV_OFFSET + pp_count * sizeof(double **));
  486. X        retval = d3 = (double ***)((char *)mvp + MV_OFFSET);
  487. X        for (i = 0; i < dimension - 3; i++) {
  488. X            count *= size[i];
  489. X            for (j = 0; j < count; j++) {
  490. X            d3[base+j] = (double **)(d3 + base + count + j * size[i+1]);
  491. X            }
  492. X                base += count;
  493. X        }
  494. X        d3[base] = MallocOrDie((long) p_count * sizeof(double *));
  495. X        count *= size[dimension-3];
  496. X        for (i = 1; i < count; i++) 
  497. X        d3[base+i] = d3[base+i-1] + size[dimension-2];
  498. X        d3[base][0] = MallocOrDie((long) el_count * sizeof(double));
  499. X        for (i = 1; i < p_count; i++)
  500. X            d3[base][i] = d3[base][i-1] + size[dimension-1];
  501. X    } else if (dimension == 2) {
  502. X        mvp = MallocOrDie((long) MV_OFFSET + p_count * sizeof(double *));
  503. X        retval = d2 = (double **)((char *)mvp + MV_OFFSET);
  504. X        d2[0] = MallocOrDie((long) el_count * sizeof(double));
  505. X        for (i = 1; i < p_count; i++)
  506. X            d2[i] = d2[i-1] + size[1];
  507. X    } else {
  508. X        mvp = MallocOrDie((long) MV_OFFSET + el_count * sizeof(double));
  509. X        retval = (double *)((char *)mvp + MV_OFFSET);
  510. X    }
  511. X    break;
  512. X      case MV_VOIDP:
  513. X    if (dimension > 2 ) {
  514. X        mvp = MallocOrDie((long)MV_OFFSET + pp_count * sizeof(VoidPtr **));
  515. X        retval = v3 = (VoidPtr ***)((char *)mvp + MV_OFFSET);
  516. X        for (i = 0; i < dimension - 3; i++) {
  517. X            count *= size[i];
  518. X            for (j = 0; j < count; j++) {
  519. X            v3[base+j] = (VoidPtr **)(v3 + base + count + j*size[i+1]);
  520. X            }
  521. X                base += count;
  522. X        }
  523. X        v3[base] = MallocOrDie((long) p_count * sizeof(VoidPtr *));
  524. X        count *= size[dimension-3];
  525. X        for (i = 1; i < count; i++) 
  526. X        v3[base+i] = v3[base+i-1] + size[dimension-2];
  527. X        v3[base][0] = MallocOrDie((long) el_count * sizeof(VoidPtr));
  528. X        for (i = 1; i < p_count; i++)
  529. X            v3[base][i] = v3[base][i-1] + size[dimension-1];
  530. X    } else if (dimension == 2) {
  531. X        mvp = MallocOrDie((long) MV_OFFSET + p_count * sizeof(VoidPtr *));
  532. X        retval = v2 = (VoidPtr **)((char *)mvp + MV_OFFSET);
  533. X        v2[0] = MallocOrDie((long) el_count * sizeof(VoidPtr));
  534. X        for (i = 1; i < p_count; i++)
  535. X            v2[i] = v2[i-1] + size[1];
  536. X    } else {
  537. X        mvp = MallocOrDie((long) MV_OFFSET + el_count * sizeof(VoidPtr));
  538. X        retval = (VoidPtr *)((char *)mvp + MV_OFFSET);
  539. X    }
  540. X    break;
  541. X      default:
  542. X    fprintf(stderr, "MValloc: illegal element type\n");
  543. X    free((void *) size);
  544. X    return 0;
  545. X    }
  546. X    if (retval) {
  547. X    mvp->magic = MV_MAGIC;
  548. X    mvp->eltype = eltype;
  549. X    mvp->dimension = dimension;
  550. X    mvp->size = size;
  551. X    }
  552. X    return retval;
  553. X}
  554. X
  555. Xvoid
  556. XMVfree(mvobj)
  557. Xvoid *mvobj;
  558. X{
  559. X    MVobj          *mvp = 0;
  560. X    char     ***c3, **c2;
  561. X    short        ***s3, **s2;
  562. X    int          ***i3, **i2;
  563. X    long         ***l3, **l2;
  564. X    float        ***f3, **f2;
  565. X    double       ***d3, **d2;
  566. X    VoidPtr      ***v3, **v2;
  567. X    long            count, base;
  568. X    int             i;
  569. X
  570. X    if (mvobj) {
  571. X    mvp = (MVobj *) ((char *)mvobj - MV_OFFSET);
  572. X    if (mvp->magic != MV_MAGIC) {
  573. X            fprintf(stderr, "MVfree: argument isn't an MVobject\n");
  574. X        return;
  575. X    }
  576. X    mvp->magic = 0;  /* in case we see this object again */
  577. X    } else  {
  578. X        fprintf(stderr, "MVfree: NULL argument\n");
  579. X    return;
  580. X    }
  581. X    base = 0;
  582. X    count = 1;
  583. X    switch (mvp->eltype) {
  584. X      case MV_CHAR:
  585. X    if (mvp->dimension > 2 ) {
  586. X        c3 = (char ***) mvobj;
  587. X        for (i = 0; i < mvp->dimension - 3; i++) {
  588. X            count *= mvp->size[i];
  589. X                base += count;
  590. X        }
  591. X        free((void *) c3[base][0]);
  592. X        free((void *) c3[base]);
  593. X    } else if (mvp->dimension == 2) {
  594. X        c2 = (char **) mvobj;
  595. X        free((void *) c2[0]);
  596. X    }
  597. X    break;
  598. X      case MV_SHORT:
  599. X    if (mvp->dimension > 2 ) {
  600. X        s3 = (short ***) mvobj;
  601. X        for (i = 0; i < mvp->dimension - 3; i++) {
  602. X            count *= mvp->size[i];
  603. X                base += count;
  604. X        }
  605. X        free((void *) s3[base][0]);
  606. X        free((void *) s3[base]);
  607. X    } else if (mvp->dimension == 2) {
  608. X        s2 = (short **) mvobj;
  609. X        free((void *) s2[0]);
  610. X    }
  611. X    break;
  612. X      case MV_INT:
  613. X    if (mvp->dimension > 2 ) {
  614. X        i3 = (int ***) mvobj;
  615. X        for (i = 0; i < mvp->dimension - 3; i++) {
  616. X            count *= mvp->size[i];
  617. X                base += count;
  618. X        }
  619. X        free((void *) i3[base][0]);
  620. X        free((void *) i3[base]);
  621. X    } else if (mvp->dimension == 2) {
  622. X        i2 = (int **) mvobj;
  623. X        free((void *) i2[0]);
  624. X    }
  625. X    break;
  626. X      case MV_LONG:
  627. X    if (mvp->dimension > 2 ) {
  628. X        l3 = (long ***) mvobj;
  629. X        for (i = 0; i < mvp->dimension - 3; i++) {
  630. X            count *= mvp->size[i];
  631. X                base += count;
  632. X        }
  633. X        free((void *) l3[base][0]);
  634. X        free((void *) l3[base]);
  635. X    } else if (mvp->dimension == 2) {
  636. X        l2 = (long **) mvobj;
  637. X        free((void *) l2[0]);
  638. X    }
  639. X    break;
  640. X      case MV_FLOAT:
  641. X    if (mvp->dimension > 2 ) {
  642. X        f3 = (float ***) mvobj;
  643. X        for (i = 0; i < mvp->dimension - 3; i++) {
  644. X            count *= mvp->size[i];
  645. X                base += count;
  646. X        }
  647. X        free((void *) f3[base][0]);
  648. X        free((void *) f3[base]);
  649. X    } else if (mvp->dimension == 2) {
  650. X        f2 = (float **) mvobj;
  651. X        free((void *) f2[0]);
  652. X    }
  653. X    break;
  654. X      case MV_DOUBLE:
  655. X    if (mvp->dimension > 2 ) {
  656. X        d3 = (double ***) mvobj;
  657. X        for (i = 0; i < mvp->dimension - 3; i++) {
  658. X            count *= mvp->size[i];
  659. X                base += count;
  660. X        }
  661. X        free((void *) d3[base][0]);
  662. X        free((void *) d3[base]);
  663. X    } else if (mvp->dimension == 2) {
  664. X        d2 = (double **) mvobj;
  665. X        free((void *) d2[0]);
  666. X    }
  667. X    break;
  668. X      case MV_VOIDP:
  669. X    if (mvp->dimension > 2 ) {
  670. X        v3 = (VoidPtr ***) mvobj;
  671. X        for (i = 0; i < mvp->dimension - 3; i++) {
  672. X            count *= mvp->size[i];
  673. X                base += count;
  674. X        }
  675. X        free((void *) v3[base][0]);
  676. X        free((void *) v3[base]);
  677. X    } else if (mvp->dimension == 2) {
  678. X        v2 = (VoidPtr **) mvobj;
  679. X        free((void *) v2[0]);
  680. X    }
  681. X    break;
  682. X      default:
  683. X    fprintf(stderr, "MVfree: illegal element type\n");
  684. X    break;
  685. X    }
  686. X    free((void *) mvp->size);
  687. X    free((void *) mvp);
  688. X}
  689. X
  690. Xint
  691. XMVdimension(mvobj)
  692. Xvoid *mvobj;
  693. X{
  694. X    MVobj         *mvp;
  695. X    int           dimension = -1;
  696. X
  697. X    if (mvobj) {
  698. X    mvp = (MVobj *) ((char *)mvobj - MV_OFFSET);
  699. X    if (mvp->magic == MV_MAGIC)
  700. X        dimension = mvp->dimension;
  701. X    else 
  702. X            fprintf(stderr, "MVdimension: argument isn't an MVobject\n");
  703. X    } else
  704. X        fprintf(stderr, "MVdimension: NULL argument\n");
  705. X    return dimension;
  706. X}
  707. X
  708. Xlong
  709. XMVsize(mvobj, dimension)
  710. Xvoid *mvobj;
  711. Xint   dimension;
  712. X{
  713. X    MVobj         *mvp;
  714. X    long           size = -1;
  715. X
  716. X    if (mvobj) {
  717. X    mvp = (MVobj *) ((char *)mvobj - MV_OFFSET);
  718. X    if (mvp->magic == MV_MAGIC) {
  719. X        if (mvp->dimension >= dimension)
  720. X            size = mvp->size[dimension];
  721. X        else
  722. X                fprintf(stderr,"MVsize: bad dimension for specified object\n");
  723. X    } else
  724. X            fprintf(stderr, "MVsize: first argument isn't an MVobject\n");
  725. X    } else
  726. X        fprintf(stderr, "MVsize: first argument is NULL\n");
  727. X    return size;
  728. X}
  729. X
  730. Xint
  731. XMVtype(mvobj)
  732. Xvoid *mvobj;
  733. X{
  734. X    MVobj         *mvp;
  735. X    int           type = -1;
  736. X
  737. X    if (mvobj) {
  738. X    mvp = (MVobj *) ((char *)mvobj - MV_OFFSET);
  739. X    if (mvp->magic == MV_MAGIC)
  740. X        type = mvp->eltype;
  741. X    else 
  742. X            fprintf(stderr, "MVtype: argument isn't an MVobject\n");
  743. X    } else
  744. X        fprintf(stderr, "MVtype: NULL argument\n");
  745. X    return type;
  746. X}
  747. END_OF_FILE
  748.   if test 16034 -ne `wc -c <'mvalloc.c'`; then
  749.     echo shar: \"'mvalloc.c'\" unpacked with wrong size!
  750.   fi
  751.   # end of 'mvalloc.c'
  752. fi
  753. if test -f 'mvalloc.h' -a "${1}" != "-c" ; then 
  754.   echo shar: Will not clobber existing file \"'mvalloc.h'\"
  755. else
  756.   echo shar: Extracting \"'mvalloc.h'\" \(1111 characters\)
  757.   sed "s/^X//" >'mvalloc.h' <<'END_OF_FILE'
  758. X#ifndef MVALLOC_H
  759. X#define MVALLOC_H
  760. X
  761. X/*
  762. X * Copyright (C) 1991, 1992 by Chris Thewalt (thewalt@ce.berkeley.edu)
  763. X *
  764. X * Permission to use, copy, modify, and distribute this software 
  765. X * for any purpose and without fee is hereby granted, provided
  766. X * that the above copyright notices appear in all copies and that both the
  767. X * copyright notice and this permission notice appear in supporting
  768. X * documentation.  This software is provided "as is" without express or
  769. X * implied warranty.
  770. X */
  771. X
  772. X
  773. X#define MV_CHAR     123
  774. X#define MV_SHORT    124
  775. X#define MV_INT      125
  776. X#define MV_LONG     126
  777. X#define MV_FLOAT    127
  778. X#define MV_DOUBLE   128
  779. X#define MV_VOIDP    129
  780. X
  781. X#ifdef __STDC__
  782. Xvoid           *MValloc(int eltype, int dimension, ...);
  783. Xvoid            MVfree(void *mvobj);
  784. Xint             MVdimension(void *mvobj);
  785. Xlong            MVsize(void *mvobj, int dimension);
  786. Xint             MVtype(void *mvobj);
  787. X#else  /* not __STDC__ */
  788. Xvoid           *MValloc();
  789. Xvoid            MVfree();
  790. Xint             MVdimension();
  791. Xlong            MVsize();
  792. Xint             MVtype();
  793. X#endif /* not __STDC__ */
  794. X
  795. X#endif /* not MVALLOC_H */
  796. END_OF_FILE
  797.   if test 1111 -ne `wc -c <'mvalloc.h'`; then
  798.     echo shar: \"'mvalloc.h'\" unpacked with wrong size!
  799.   fi
  800.   # end of 'mvalloc.h'
  801. fi
  802. if test -f 'test1.c' -a "${1}" != "-c" ; then 
  803.   echo shar: Will not clobber existing file \"'test1.c'\"
  804. else
  805.   echo shar: Extracting \"'test1.c'\" \(868 characters\)
  806.   sed "s/^X//" >'test1.c' <<'END_OF_FILE'
  807. X#include <stdio.h>
  808. X#include "mvalloc.h"
  809. X
  810. Xvoid            m_init();
  811. Xdouble          m_sum();
  812. Xdouble          sum();
  813. X
  814. Xvoid
  815. Xmain()
  816. X{
  817. X    double         *x;
  818. X    long            numel;
  819. X
  820. X    x = MValloc(MV_DOUBLE, 1, 5L);
  821. X    numel = MVsize((void *)x, 0);
  822. X    m_init(x);
  823. X    printf("sum of elements is %.14g (should be %.14g)\n", 
  824. X       m_sum(x), sum(numel-1));
  825. X    MVfree((void *)x);
  826. X}
  827. X
  828. Xvoid
  829. Xm_init(x)
  830. Xdouble *x;
  831. X{
  832. X    long             d1;
  833. X    long             i;
  834. X    double           val = 0.0;
  835. X
  836. X    d1 = MVsize((void *)x, 0);
  837. X    for (i = 0; i < d1; i++)
  838. X    x[i] = val++;
  839. X}
  840. X
  841. Xdouble
  842. Xm_sum(x)
  843. Xdouble *x;
  844. X{
  845. X    long             d1;
  846. X    long             i;
  847. X    double           val = 0.0;
  848. X
  849. X    d1 = MVsize((void *)x, 0);
  850. X    for (i = 0; i < d1; i++)
  851. X    val += x[i];
  852. X    return val;
  853. X}
  854. X
  855. Xdouble
  856. Xsum(i)
  857. Xlong i;
  858. X{
  859. X    double val = 0.0;
  860. X
  861. X    while (i > 0)
  862. X    val += i--;
  863. X    return val;
  864. X}
  865. END_OF_FILE
  866.   if test 868 -ne `wc -c <'test1.c'`; then
  867.     echo shar: \"'test1.c'\" unpacked with wrong size!
  868.   fi
  869.   # end of 'test1.c'
  870. fi
  871. if test -f 'test2.c' -a "${1}" != "-c" ; then 
  872.   echo shar: Will not clobber existing file \"'test2.c'\"
  873. else
  874.   echo shar: Extracting \"'test2.c'\" \(1041 characters\)
  875.   sed "s/^X//" >'test2.c' <<'END_OF_FILE'
  876. X#include <stdio.h>
  877. X#include "mvalloc.h"
  878. X
  879. Xvoid            m_init();
  880. Xdouble          m_sum();
  881. Xdouble          sum();
  882. X
  883. Xvoid
  884. Xmain()
  885. X{
  886. X    double         **x;
  887. X    long             numel;
  888. X
  889. X    x = MValloc(MV_DOUBLE, 2, 5L, 5L);
  890. X    numel = MVsize((void *)x, 0) * MVsize((void *)x, 1);
  891. X    m_init(x);
  892. X    printf("sum of elements is %.14g (should be %.14g)\n", 
  893. X       m_sum(x), sum(numel-1));
  894. X    MVfree((void *)x);
  895. X}
  896. X
  897. Xvoid
  898. Xm_init(x)
  899. Xdouble **x;
  900. X{
  901. X    long             d1, d2;
  902. X    long             i, j;
  903. X    double           val = 0.0;
  904. X
  905. X    d1 = MVsize((void *)x, 0);
  906. X    d2 = MVsize((void *)x, 1);
  907. X    for (i = 0; i < d1; i++)
  908. X    for (j = 0; j < d2; j++)
  909. X        x[i][j] = val++;
  910. X}
  911. X
  912. Xdouble
  913. Xm_sum(x)
  914. Xdouble **x;
  915. X{
  916. X    long             d1, d2;
  917. X    long             i, j;
  918. X    double           val = 0.0;
  919. X
  920. X    d1 = MVsize((void *)x, 0);
  921. X    d2 = MVsize((void *)x, 1);
  922. X    for (i = 0; i < d1; i++)
  923. X    for (j = 0; j < d2; j++)
  924. X        val += x[i][j];
  925. X    return val;
  926. X}
  927. X
  928. Xdouble
  929. Xsum(i)
  930. Xlong i;
  931. X{
  932. X    double val = 0.0;
  933. X
  934. X    while (i > 0)
  935. X    val += i--;
  936. X    return val;
  937. X}
  938. END_OF_FILE
  939.   if test 1041 -ne `wc -c <'test2.c'`; then
  940.     echo shar: \"'test2.c'\" unpacked with wrong size!
  941.   fi
  942.   # end of 'test2.c'
  943. fi
  944. if test -f 'test3.c' -a "${1}" != "-c" ; then 
  945.   echo shar: Will not clobber existing file \"'test3.c'\"
  946. else
  947.   echo shar: Extracting \"'test3.c'\" \(1227 characters\)
  948.   sed "s/^X//" >'test3.c' <<'END_OF_FILE'
  949. X#include <stdio.h>
  950. X#include "mvalloc.h"
  951. X
  952. Xvoid            m_init();
  953. Xdouble          m_sum();
  954. Xdouble          sum();
  955. X
  956. Xvoid
  957. Xmain()
  958. X{
  959. X    double         ***x;
  960. X    long              numel;
  961. X
  962. X    x = MValloc(MV_DOUBLE, 3, 5L, 5L, 5L);
  963. X    numel = MVsize((void *)x, 0) * MVsize((void *)x, 1) *
  964. X        MVsize((void *)x, 2);
  965. X    m_init(x);
  966. X    printf("sum of elements is %.14g (should be %.14g)\n", 
  967. X       m_sum(x), sum(numel-1));
  968. X    MVfree((void *)x);
  969. X}
  970. X
  971. Xvoid
  972. Xm_init(x)
  973. Xdouble ***x;
  974. X{
  975. X    long             d1, d2, d3;
  976. X    long             i, j, k;
  977. X    double           val = 0.0;
  978. X
  979. X    d1 = MVsize((void *)x, 0);
  980. X    d2 = MVsize((void *)x, 1);
  981. X    d3 = MVsize((void *)x, 2);
  982. X    for (i = 0; i < d1; i++)
  983. X    for (j = 0; j < d2; j++)
  984. X        for (k = 0; k < d3; k++)
  985. X            x[i][j][k] = val++;
  986. X}
  987. X
  988. Xdouble
  989. Xm_sum(x)
  990. Xdouble ***x;
  991. X{
  992. X    long             d1, d2, d3;
  993. X    long             i, j, k;
  994. X    double           val = 0.0;
  995. X
  996. X    d1 = MVsize((void *)x, 0);
  997. X    d2 = MVsize((void *)x, 1);
  998. X    d3 = MVsize((void *)x, 2);
  999. X    for (i = 0; i < d1; i++)
  1000. X    for (j = 0; j < d2; j++)
  1001. X        for (k = 0; k < d3; k++)
  1002. X            val += x[i][j][k];
  1003. X    return val;
  1004. X}
  1005. X
  1006. Xdouble
  1007. Xsum(i)
  1008. Xlong i;
  1009. X{
  1010. X    double val = 0.0;
  1011. X
  1012. X    while (i > 0)
  1013. X    val += i--;
  1014. X    return val;
  1015. X}
  1016. END_OF_FILE
  1017.   if test 1227 -ne `wc -c <'test3.c'`; then
  1018.     echo shar: \"'test3.c'\" unpacked with wrong size!
  1019.   fi
  1020.   # end of 'test3.c'
  1021. fi
  1022. if test -f 'test4.c' -a "${1}" != "-c" ; then 
  1023.   echo shar: Will not clobber existing file \"'test4.c'\"
  1024. else
  1025.   echo shar: Extracting \"'test4.c'\" \(1416 characters\)
  1026.   sed "s/^X//" >'test4.c' <<'END_OF_FILE'
  1027. X#include <stdio.h>
  1028. X#include "mvalloc.h"
  1029. X
  1030. Xvoid            m_init();
  1031. Xdouble          m_sum();
  1032. Xdouble          sum();
  1033. X
  1034. Xvoid
  1035. Xmain()
  1036. X{
  1037. X    double         ****x;
  1038. X    long               numel;
  1039. X
  1040. X    x = MValloc(MV_DOUBLE, 4, 5L, 5L, 5L, 5L);
  1041. X    numel = MVsize((void *)x, 0) * MVsize((void *)x, 1) *
  1042. X        MVsize((void *)x, 2) * MVsize((void *)x, 3);
  1043. X    m_init(x);
  1044. X    printf("sum of elements is %.14g (should be %.14g)\n", 
  1045. X       m_sum(x), sum(numel-1));
  1046. X    MVfree((void *)x);
  1047. X}
  1048. X
  1049. Xvoid
  1050. Xm_init(x)
  1051. Xdouble ****x;
  1052. X{
  1053. X    long             d1, d2, d3, d4;
  1054. X    long             i, j, k, l;
  1055. X    double           val = 0.0;
  1056. X
  1057. X    d1 = MVsize((void *)x, 0);
  1058. X    d2 = MVsize((void *)x, 1);
  1059. X    d3 = MVsize((void *)x, 2);
  1060. X    d4 = MVsize((void *)x, 3);
  1061. X    for (i = 0; i < d1; i++)
  1062. X    for (j = 0; j < d2; j++)
  1063. X        for (k = 0; k < d3; k++)
  1064. X            for (l = 0; l < d4; l++)
  1065. X                x[i][j][k][l] = val++;
  1066. X}
  1067. X
  1068. Xdouble
  1069. Xm_sum(x)
  1070. Xdouble ****x;
  1071. X{
  1072. X    long             d1, d2, d3, d4;
  1073. X    long             i, j, k, l;
  1074. X    double           val = 0.0;
  1075. X
  1076. X    d1 = MVsize((void *)x, 0);
  1077. X    d2 = MVsize((void *)x, 1);
  1078. X    d3 = MVsize((void *)x, 2);
  1079. X    d4 = MVsize((void *)x, 3);
  1080. X    for (i = 0; i < d1; i++)
  1081. X    for (j = 0; j < d2; j++)
  1082. X        for (k = 0; k < d3; k++)
  1083. X            for (l = 0; l < d4; l++)
  1084. X                val += x[i][j][k][l];
  1085. X    return val;
  1086. X}
  1087. X
  1088. Xdouble
  1089. Xsum(i)
  1090. Xlong i;
  1091. X{
  1092. X    double val = 0.0;
  1093. X
  1094. X    while (i > 0)
  1095. X    val += i--;
  1096. X    return val;
  1097. X}
  1098. END_OF_FILE
  1099.   if test 1416 -ne `wc -c <'test4.c'`; then
  1100.     echo shar: \"'test4.c'\" unpacked with wrong size!
  1101.   fi
  1102.   # end of 'test4.c'
  1103. fi
  1104. if test -f 'test5.c' -a "${1}" != "-c" ; then 
  1105.   echo shar: Will not clobber existing file \"'test5.c'\"
  1106. else
  1107.   echo shar: Extracting \"'test5.c'\" \(1576 characters\)
  1108.   sed "s/^X//" >'test5.c' <<'END_OF_FILE'
  1109. X#include <stdio.h>
  1110. X#include "mvalloc.h"
  1111. X
  1112. Xvoid            m_init();
  1113. Xint          m_sum();
  1114. Xint          sum();
  1115. X
  1116. Xvoid
  1117. Xmain()
  1118. X{
  1119. X    int         *****x;
  1120. X    long                numel;
  1121. X
  1122. X    x = MValloc(MV_DOUBLE, 5, 3L, 4L, 5L, 6L, 7L);
  1123. X    numel = MVsize((void *)x, 0) * MVsize((void *)x, 1) *
  1124. X        MVsize((void *)x, 2) * MVsize((void *)x, 3) *
  1125. X        MVsize((void *)x, 4);
  1126. X    m_init(x);
  1127. X    printf("sum of elements is %d (should be %d)\n", 
  1128. X       m_sum(x), sum(numel-1));
  1129. X    MVfree((void *)x);
  1130. X}
  1131. X
  1132. Xvoid
  1133. Xm_init(x)
  1134. Xint *****x;
  1135. X{
  1136. X    long             d1, d2, d3, d4, d5;
  1137. X    long             i, j, k, l, m;
  1138. X    int           val = 0;
  1139. X
  1140. X    d1 = MVsize((void *)x, 0);
  1141. X    d2 = MVsize((void *)x, 1);
  1142. X    d3 = MVsize((void *)x, 2);
  1143. X    d4 = MVsize((void *)x, 3);
  1144. X    d5 = MVsize((void *)x, 4);
  1145. X    for (i = 0; i < d1; i++)
  1146. X    for (j = 0; j < d2; j++)
  1147. X        for (k = 0; k < d3; k++)
  1148. X            for (l = 0; l < d4; l++)
  1149. X                for (m = 0; m < d5; m++)
  1150. X                    x[i][j][k][l][m] = val++;
  1151. X}
  1152. X
  1153. Xint
  1154. Xm_sum(x)
  1155. Xint *****x;
  1156. X{
  1157. X    long             d1, d2, d3, d4, d5;
  1158. X    long             i, j, k, l, m;
  1159. X    int           val = 0;
  1160. X
  1161. X    d1 = MVsize((void *)x, 0);
  1162. X    d2 = MVsize((void *)x, 1);
  1163. X    d3 = MVsize((void *)x, 2);
  1164. X    d4 = MVsize((void *)x, 3);
  1165. X    d5 = MVsize((void *)x, 4);
  1166. X    for (i = 0; i < d1; i++)
  1167. X    for (j = 0; j < d2; j++)
  1168. X        for (k = 0; k < d3; k++)
  1169. X            for (l = 0; l < d4; l++)
  1170. X                for (m = 0; m < d5; m++)
  1171. X                    val += x[i][j][k][l][m];
  1172. X    return val;
  1173. X}
  1174. X
  1175. Xint
  1176. Xsum(i)
  1177. Xlong i;
  1178. X{
  1179. X    int val = 0;
  1180. X
  1181. X    while (i > 0)
  1182. X    val += i--;
  1183. X    return val;
  1184. X}
  1185. END_OF_FILE
  1186.   if test 1576 -ne `wc -c <'test5.c'`; then
  1187.     echo shar: \"'test5.c'\" unpacked with wrong size!
  1188.   fi
  1189.   # end of 'test5.c'
  1190. fi
  1191. echo shar: End of archive 1 \(of 1\).
  1192. cp /dev/null ark1isdone
  1193. MISSING=""
  1194. for I in 1 ; do
  1195.     if test ! -f ark${I}isdone ; then
  1196.     MISSING="${MISSING} ${I}"
  1197.     fi
  1198. done
  1199. if test "${MISSING}" = "" ; then
  1200.     echo You have the archive.
  1201.     rm -f ark[1-9]isdone
  1202. else
  1203.     echo You still must unpack the following archives:
  1204.     echo "        " ${MISSING}
  1205. fi
  1206. exit 0
  1207. exit 0 # Just in case...
  1208.