home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / info-service / gopher / Unix / gopher1.12 / object / DAarray.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-30  |  4.8 KB  |  260 lines

  1. /********************************************************************
  2.  * $Author: lindner $
  3.  * $Revision: 1.3 $
  4.  * $Date: 1992/12/21 21:14:57 $
  5.  * $Source: /home/mudhoney/GopherSrc/release1.11/object/RCS/DAarray.c,v $
  6.  * $State: Rel $
  7.  *
  8.  * Paul Lindner, University of Minnesota CIS.
  9.  *
  10.  * Copyright 1991, 1992 by the Regents of the University of Minnesota
  11.  * see the file "Copyright" in the distribution for conditions of use.
  12.  *********************************************************************
  13.  * MODULE: DAarray.c
  14.  * Dynamic Array Implementation
  15.  *********************************************************************
  16.  * Revision History:
  17.  * $Log: DAarray.c,v $
  18.  * Revision 1.3  1992/12/21  21:14:57  lindner
  19.  * Fixed bug in DAcpy, initfn wasn't being copied right.
  20.  *
  21.  * Revision 1.2  1992/12/21  20:04:04  lindner
  22.  * Added DAcpy()
  23.  *
  24.  * Revision 1.1  1992/12/10  23:27:52  lindner
  25.  * gopher 1.1 release
  26.  *
  27.  *
  28.  *********************************************************************/
  29.  
  30.  
  31. #include "DAarray.h"
  32.  
  33. #include "Malloc.h"
  34.  
  35. /*
  36.  * Create a new dynamic array
  37.  *
  38.  * size      -- the initial number of elements
  39.  * newfn     -- creates new object
  40.  * initfn    -- initializes the object
  41.  * destroyfn -- performs clean up and frees objs memory
  42.  * copyfn    -- copys one obj to the other, like strcpy
  43.  */
  44.  
  45. DynArray *
  46. DAnew(size, newfn, initfn, destroyfn, copyfn)
  47.   int size;
  48.   char * (*newfn)();
  49.   void   (*initfn)();
  50.   void   (*destroyfn)();
  51.   char * (*copyfn)();
  52. {
  53.      DynArray *temp;
  54.      int i;
  55.      
  56.      temp = (DynArray*) malloc(sizeof(DynArray));
  57.      temp->objects = (char **) malloc(size * sizeof(char *));
  58.      temp->newfn     = newfn;
  59.      temp->initfn    = initfn;
  60.      temp->destroyfn = destroyfn;
  61.      temp->copyfn    = copyfn;
  62.      temp->Top       = 0;
  63.  
  64.      if (copyfn == NULL)
  65.       /** Can't work without this!!! ***/
  66.       perror("Egad, no copy function in DAnew()!!");
  67.  
  68.      if (newfn != NULL)
  69.       for (i = 0; i < size; i++)
  70.            temp->objects[i] = (char *) newfn();
  71.  
  72.      temp->maxsize = size;
  73.      return(temp);
  74. }
  75.  
  76.  
  77. void DAdestroy(da)
  78.   DynArray *da;
  79. {
  80.      int i;
  81.      
  82.      if (da->destroyfn != NULL)
  83.       for (i = 0; i< da->maxsize; i++)
  84.            da->destroyfn(da->objects[i]);
  85.  
  86.      free(da->objects);
  87.      free(da);
  88. }
  89.  
  90.  
  91. void
  92. DAinit(da)
  93.   DynArray *da;
  94. {
  95.      int i;
  96.      
  97.      if (da->initfn!=NULL)
  98.       for (i=0; i<da->maxsize; i++)
  99.            da->initfn(DAgetEntry(da, i));
  100.  
  101.      DAsetTop(da, 0);
  102. }
  103.  
  104. void
  105. DAgrow(da, size)
  106.   DynArray *da;
  107.   int size;
  108. {
  109.      char **temp;
  110.      int i;
  111.  
  112.      if (size < da->maxsize)
  113.       return; /** Size is smaller than requested **/
  114.  
  115.      temp = (char **) realloc(da->objects, size*sizeof(char*));
  116.  
  117.      if (temp == NULL)
  118.       perror("Out of memory!!!\n"), exit(-1);
  119.  
  120.      if (temp != da->objects) {
  121.       da->objects = temp;
  122.      }
  123.  
  124.      /** Initialize the new objects.  **/
  125.  
  126.      for (i= da->maxsize; i< size; i++)
  127.       da->objects[i] = da->newfn();
  128.      
  129.      da->maxsize = size;
  130.      return;
  131. }
  132.  
  133. /*
  134.  * Tacks an item on the end of the array, grows it if necessary..
  135.  */
  136.  
  137. void
  138. DApush(da, obj)
  139.   DynArray *da;
  140.   char *obj;
  141. {
  142.      int top;
  143.  
  144.      top = DAgetTop(da);
  145.      
  146.      if (top == da->maxsize)
  147.       DAgrow(da, da->maxsize*2);
  148.  
  149.      da->copyfn(DAgetEntry(da, top), obj);
  150.  
  151.      DAsetTop(da, top+1);                /* update end of list */
  152. }
  153.  
  154. char *
  155. DApop(da)
  156.   DynArray *da;
  157. {
  158.      int top;
  159.      char *newobj;
  160.      
  161.      top = DAgetTop(da);
  162.  
  163.      if (top == 0)
  164.       return(NULL);  /** Nothing to pop! **/
  165.  
  166.      newobj = da->newfn();
  167.      da->initfn(newobj);
  168.      
  169.      da->copyfn(newobj, DAgetEntry(da, top+1));
  170.  
  171.      top--;
  172.      DAsetTop(da, top);
  173.  
  174.      return(newobj);
  175. }
  176.  
  177. void 
  178. DAsort(da, sortfn)
  179.   DynArray *da;
  180.   int (*sortfn)();
  181. {
  182.      char *moo;
  183.  
  184.      moo = (char *) &((da->objects)[0]);
  185.      
  186.      qsort(moo, da->Top,
  187.        sizeof(char *), sortfn);
  188. }
  189.  
  190.  
  191. void
  192. DAcpy(dest, orig)
  193.   DynArray *dest;
  194.   DynArray *orig;
  195. {
  196.      int i;
  197.  
  198.      DAsetTop(dest, 0);
  199.      dest->newfn = orig->newfn;
  200.      dest->initfn = orig->initfn;
  201.      dest->destroyfn = orig->destroyfn;
  202.      dest->copyfn = dest->copyfn;
  203.  
  204.      for (i=0; i<DAgetTop(orig); i++) {
  205.       DApush(dest, DAgetEntry(orig,i));
  206.      }
  207. }
  208. #ifdef DA_TEST
  209.  
  210. #include <stdio.h>
  211. #include <string.h>
  212.  
  213. char *makespace()
  214. {
  215.      return(malloc(256));
  216. }
  217.  
  218. int DEBUG = 1;
  219.  
  220. int
  221. moostrcmp(s1, s2)
  222.   char **s1, **s2;
  223. {
  224.      printf("Comparing %s, %s\n", *s1,*s2);
  225.      return(strcmp(*s1,*s2));
  226. }
  227.  
  228. main()
  229. {
  230.      DynArray *test;
  231.      int i;
  232.      char tempstr[100];
  233.  
  234.      printf("Testing Dynamic Arrays...\n\n");
  235.      
  236.      test = DAnew(5, makespace, NULL, NULL, strcpy);
  237.  
  238.      DApush(test, "ziggy\n");
  239.      DApush(test, "iggy\n");
  240.      
  241.      for (i= 10; i >0; i--) {
  242.       sprintf(tempstr, "Moocow #%d\n", i);
  243.       printf(tempstr);
  244.       DApush(test, tempstr);
  245.      }
  246.  
  247.      for (i=0; i< 10; i++) {
  248.       printf(DAgetEntry(test, i));
  249.      }
  250.  
  251.      DAsort(test, moostrcmp);
  252.  
  253.      for (i=0; i< 10; i++) {
  254.       printf(DAgetEntry(test, i));
  255.      }
  256.  
  257. }
  258.  
  259. #endif
  260.