    /* $Id: select.cpp 1.2 1995/02/27 12:22:03 leon Exp leon $
    */

    #include "select.h"

    #include <malloc.h>

    #undef DEBUG

    static void (*inOrderFunc)(ads_name name);

    /**
     ** Naredi prazen izbor
     **/
    Selection::Selection()
    {
      root = NULL;
    }

    /** {duh} **/
    Selection::~Selection()
    {
      typedef void (*DELFUNC) (void *);
      if (root)
        AVLrelease(&root, (DELFUNC) del);
    }

    /**
     ** Izbere gradnike iz ACAD baze podane s filtrom /xFilter/, nato pa
     ** z uporabo funkcije /getKey/ izbere kljuc /key/ iz gradnika in zgradi
     ** AVL drevo, ki za vsak element poleg kljuca hrani se ime gradnika /name/.
     ** Kljuc se lahko nahaja tudi v extended data, za kar je potrebno podati
     ** se /apps/ za ads_entgetx(). Funkcija /getKey/ mora vrniti 0, ce je nasla
     ** kljuc.
     **/
    Selection::Select(struct resbuf *xFilter,
                      int (*getKey)(struct resbuf *rb, int *key),
                      struct resbuf *apps)
    {
      struct resbuf *rb;
      ads_name ss;
      long ssLength, i;
      int status, key;

      status = ads_ssget("X", NULL, NULL,  xFilter, ss);

      if (status != RTNORM)
        return -1;

      ads_sslength(ss, &ssLength);
    #ifdef DEBUG

      ads_printf ("Stevilo izbranih elementov: %ld\n", ssLength);
    #endif

      for (i = 0; i < ssLength; i++)
        {
          ads_name ent;
          status = ads_ssname(ss, i, ent);
          if (status != RTNORM)
            return status;
          rb = ads_entgetx(ent, apps);
          if (rb == NULL)
            continue;
          if ( (getKey)(rb, &key) == 0)
            Insert(key, ent);

          ads_relrb (rb);
        }

      ads_ssfree (ss);

      return 0;
    }

    /**
     ** Vrine en element v seznam
     **/
    int Selection::Insert(int key, ads_name name)
    {
      typedef int (*COMPAREFUNC) (void *, void *);
      struct ELEMENT *element;

      element = (struct ELEMENT *) malloc (sizeof (struct ELEMENT));
      if (!element)
        return AVL_NO_MEM;
      element->number = key;
      element->name[0] = name[0];
      element->name[1] = name[1];
      return AVLinsert(element, &root, (COMPAREFUNC) compare);
    }

    /**
     ** Zbrise element iz izbora
     **/
    int Selection::Delete(int key)
    {
      typedef int (*COMPAREFUNC) (void *, void *);
      typedef void (*DELFUNC) (void *);
      struct ELEMENT element;
      element.number = key;
      return AVLdelete(&element, &root, (COMPAREFUNC)compare, (DELFUNC)del);
    }

    /**
     ** Poisce element v izboru in vrne ACL_OK, ce je vse v redu ter
     ** /name/ gradnika. Ob napaki vrne -1;
     **/
    int Selection::Find(int key, ads_name name)
    {
      typedef int (*COMPAREFUNC) (void *, void *);
      struct ELEMENT element, *e;

      element.number = key;
      if (( e = (ELEMENT *)AVLfind(&element, root,
                                   (COMPAREFUNC) compare)) == NULL)
        return -1;
      name[0] = e->name[0];
      name[1] = e->name[1];
      return AVL_OK;
    }

    /**
     ** Samo za razhroscevanje in testiranje. Izpise drevo v urejenem vrstnem
     ** redu po kljucih.
     **/
    void Selection::Print()
    {
      typedef void (*PRINTFUNC) (void *);
      ads_printf("Seznam elementov, ki so v seznamu:\n");
      AVLinorder(root, (PRINTFUNC) print);
      ads_printf("\n");
    }

    /**
     ** V pravilnem vrstnem redu za vse gradnike izbora izvrsi to funkcijo
     **/

    void Selection::ForAll(void (*func)(ads_name name))
    {
      typedef void (*INORDERFUNC) (void *);
      inOrderFunc = func;
      AVLinorder(root, (INORDERFUNC) inOrder);
    }

    /**
     ** Zbrise en element, tako da sprosti spomin zanj.
     **/
    void Selection::del(struct ELEMENT *element)
    {
      free (element);
    }

    /**
     ** Primerja dva elementa v drevesu AVL glede na velikost
     **/
    int  Selection::compare(struct ELEMENT *el1, struct ELEMENT *el2)
    {
      if (el1->number > el2->number)
        return 1;
      if (el1->number < el2->number)
        return -1;
      return 0;
    }

    /**
     ** Izpise en element na zaslon
     **/
    void Selection::print(struct ELEMENT *element)
    {
      ads_printf("[%d]", element->number);
    }

    void Selection::inOrder(struct ELEMENT *element)
    {
      (*inOrderFunc)(element->name);
    }

syntax highlighted by Code2HTML, v. 0.9.1