home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / windows / c / wxwin140 / src / wx_list.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-18  |  9.2 KB  |  480 lines

  1. /*
  2.  * File:     wx_list.cc
  3.  * Purpose:  List implementation
  4.  *
  5.  *                        wxWindows 1.40
  6.  * Copyright (c) 1993 Artificial Intelligence Applications Institute,
  7.  *                   The University of Edinburgh
  8.  *
  9.  *                     Author: Julian Smart
  10.  *                       Date: 18-4-93
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose is hereby granted without fee, provided
  14.  * that the above copyright notice, author statement and this permission
  15.  * notice appear in all copies of this software and related documentation.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
  18.  * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
  19.  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
  22.  * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
  23.  * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
  24.  * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
  25.  * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
  26.  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  */
  28.  
  29. #include <windows.h>
  30. #include <stdarg.h>
  31. #include <stdlib.h>
  32. #include "common.h"
  33. #include "wx_list.h"
  34. #include "wx_utils.h"
  35.  
  36. wxNode::wxNode(wxList *the_list, wxNode *last_one, wxNode *next_one,
  37.                wxObject *object)
  38. {
  39.   data = object;
  40.   previous = last_one;
  41.   next = next_one;
  42.   list = the_list;
  43.   key.string = NULL;
  44.  
  45.   if (previous)
  46.     previous->next = this;
  47.  
  48.   if (next)
  49.     next->previous = this;
  50. }
  51.  
  52. // Keyed constructor
  53. wxNode::wxNode(wxList *the_list, wxNode *last_one, wxNode *next_one,
  54.                wxObject *object, long the_key)
  55. {
  56.   data = object;
  57.   previous = last_one;
  58.   next = next_one;
  59.   list = the_list;
  60.   key.integer = the_key;
  61.  
  62.   if (previous)
  63.     previous->next = this;
  64.  
  65.   if (next)
  66.     next->previous = this;
  67. }
  68.  
  69. wxNode::wxNode(wxList *the_list, wxNode *last_one, wxNode *next_one,
  70.                wxObject *object, char *the_key)
  71. {
  72.   data = object;
  73.   previous = last_one;
  74.   next = next_one;
  75.   list = the_list;
  76.   key.string = copystring(the_key);
  77.  
  78.   if (previous)
  79.     previous->next = this;
  80.  
  81.   if (next)
  82.     next->previous = this;
  83. }
  84.  
  85.  
  86. wxNode::~wxNode(void)
  87. {
  88.   if (list)
  89.     list->n --;
  90.  
  91.   if (list && list->destroy_data)
  92.     delete data;
  93.  
  94.   if (list && list->key_type == wxKEY_STRING && key.string)
  95.     delete key.string;
  96.  
  97.   // Make next node point back to the previous node from here
  98.   if (next)
  99.     next->previous = previous;
  100.   else if (list)
  101.     // If there's a new end of list (deleting the last one)
  102.     // make sure the list knows about it.
  103.     list->last_node = previous;
  104.  
  105.   // Make the previous node point to the next node from here
  106.   if (previous)
  107.     previous->next = next;
  108.  
  109.   // Or if no previous node (start of list), make sure list points at
  110.   // the next node which becomes the first!.
  111.   else if (list)
  112.     list->first_node = next;
  113. }
  114.  
  115. wxList::wxList(void)
  116. {
  117.   first_node = NULL;
  118.   last_node = NULL;
  119.   n = 0;
  120.   destroy_data = 0;
  121.   key_type = wxKEY_NONE;
  122. }
  123.  
  124. wxList::wxList(int N, wxObject *Objects[])
  125. {
  126.   wxNode *last = NULL;
  127.  
  128.   for (int i = 0; i < N; i ++)
  129.   {
  130.     wxNode *next = new wxNode(this, last, NULL, Objects[i]);
  131.     last = next;
  132.     if (i == 0) first_node = next;
  133.   }
  134.   last_node = last;
  135.   n = N;
  136.   key_type = wxKEY_NONE;
  137. }
  138.  
  139. wxList::wxList(unsigned int the_key_type)
  140. {
  141.   n = 0;
  142.   destroy_data = 0;
  143.   first_node = NULL;
  144.   last_node = NULL;
  145.   key_type = the_key_type;
  146. }
  147.  
  148. // Variable argument list, terminated by a zero
  149. wxList::wxList(wxObject *first_one ...)
  150. {
  151.   va_list ap;
  152.  
  153.   va_start(ap, first_one);
  154.  
  155.   wxNode *last = new wxNode(this, NULL, NULL, first_one);
  156.   first_node = last;
  157.   n = 1;
  158.  
  159.   for (;;)
  160.   {
  161.     wxObject *object = va_arg(ap, wxObject *);
  162.     if (((int)object) == 0)
  163.       break;
  164.     else
  165.       { wxNode *node = new wxNode(this, last, NULL, object);
  166.         last = node;
  167.         n++;
  168.       }
  169.   }
  170.   last_node = last;
  171.   va_end(ap);
  172.  
  173.   destroy_data = 0;
  174.   key_type = wxKEY_NONE;
  175. }
  176.  
  177. wxList::~wxList(void)
  178. {
  179.   wxNode *each = first_node;
  180.   while (each)
  181.   {
  182.     wxNode *next = each->Next();
  183.     delete each;
  184.     each = next;
  185.   }
  186. }
  187.  
  188. wxNode *wxList::Nth(int i)
  189. {
  190.   int j = 0;
  191.   wxNode *current = First();
  192.   while (current && j < i)
  193.   {
  194.     current = current->Next();
  195.     j ++;
  196.   }
  197.   if (j == i)
  198.     return current;
  199.   else
  200.     return NULL;
  201. }
  202.  
  203. wxNode *wxList::Find(long key)
  204. {
  205.   wxNode *current = First();
  206.   wxNode *found = NULL;
  207.   while (current && !found)
  208.   {
  209.     if (current->key.integer == key)
  210.       found = current;
  211.     else current = current->Next();
  212.   }
  213.   return found;
  214. }
  215.  
  216. wxNode *wxList::Find(char *key)
  217. {
  218.   wxNode *current = First();
  219.   wxNode *found = NULL;
  220.   while (current && !found)
  221.   {
  222.     if (strcmp(current->key.string, key) == 0)
  223.       found = current;
  224.     else current = current->Next();
  225.   }
  226.   return found;
  227. }
  228.  
  229. wxNode *wxList::Member(wxObject *object)
  230. {
  231.   wxNode *current = First();
  232.   wxNode *found = NULL;
  233.   while (current && !found)
  234.   {
  235.     wxObject *each = current->Data();
  236.     if (each == object)
  237.       found = current;
  238.     else current = current->Next();
  239.   }
  240.   return found;
  241. }
  242.  
  243. Bool wxList::DeleteNode(wxNode *node)
  244. {
  245.   if (node)
  246.   {
  247.     delete node;
  248.     return TRUE;
  249.   }
  250.   else
  251.     return FALSE;
  252. }
  253.  
  254. Bool wxList::DeleteObject(wxObject *object)
  255. {
  256.   wxNode *current = first_node;
  257.   while (current)
  258.   {
  259.     if (current->Data() == object)
  260.       break;
  261.     else current = current->Next();
  262.   }
  263.   if (current)
  264.   {
  265.     delete current;
  266.     return TRUE;
  267.   }  else return FALSE;
  268. }
  269.  
  270.  
  271. // Insert new node at front of list
  272. wxNode *wxList::Insert(wxObject *object)
  273. {
  274.   wxNode *node = new wxNode(this, NULL, First(), object);
  275.   first_node = node;
  276.  
  277.   if (!(node->Next()))
  278.     last_node = node;
  279.  
  280.   n ++;
  281.   return node;
  282. }
  283.  
  284.  
  285. // Insert new node before given node.
  286. wxNode *wxList::Insert(wxNode *position, wxObject *object)
  287. {
  288.   wxNode *prev = NULL;
  289.   if (position)
  290.     prev = position->Previous();
  291.  
  292.   wxNode *node = new wxNode(this, prev, position, object);
  293.   if (!first_node)
  294.   {
  295.     first_node = node;
  296.     last_node = node;
  297.   }
  298.   if (!prev)
  299.     first_node = node;
  300.  
  301.   n ++;
  302.   return node;
  303. }
  304.  
  305. // Keyed append
  306. wxNode *wxList::Append(long key, wxObject *object)
  307. {
  308.   wxNode *node = new wxNode(this, last_node, NULL, object, key);
  309.   if (!first_node)
  310.     first_node = node;
  311.   last_node = node;
  312.   n ++;
  313.   return node;
  314. }
  315.  
  316. wxNode *wxList::Append(char *key, wxObject *object)
  317. {
  318.   wxNode *node = new wxNode(this, last_node, NULL, object, key);
  319.   if (!first_node)
  320.     first_node = node;
  321.   last_node = node;
  322.   n ++;
  323.   return node;
  324. }
  325.  
  326. void wxList::Clear(void)
  327. {
  328.   wxNode *current = first_node;
  329.   while (current)
  330.   {
  331.     wxNode *next = current->Next();
  332.     delete current;
  333.     current = next;
  334.   }
  335.   first_node = NULL;
  336.   last_node = NULL;
  337.   n = 0;
  338. }
  339.  
  340. /*
  341.  * String list
  342.  *
  343.  */
  344.  
  345. wxStringList::wxStringList(void):wxList()
  346. {
  347. }
  348.  
  349. // Variable argument list, terminated by a zero
  350. // Makes new storage for the strings
  351. wxStringList::wxStringList(char *first ...)
  352. {
  353.   n = 0;
  354.   destroy_data = 0;
  355.   key_type = wxKEY_NONE;
  356.   first_node = NULL;
  357.   last_node = NULL;
  358.  
  359.   if (!first)
  360.     return;
  361.  
  362.   va_list ap;
  363.  
  364.   va_start(ap, first);
  365.  
  366.   wxNode *last = new wxNode(this, NULL, NULL, (wxObject *)copystring(first));
  367.   first_node = last;
  368.   n = 1;
  369.  
  370.   for (;;)
  371.   {
  372.     char *s = va_arg(ap, char *);
  373.     if (((int)s) == 0)
  374.       break;
  375.     else
  376.       { wxNode *node = new wxNode(this, last, NULL, (wxObject *)copystring(s));
  377.         last = node;
  378.         n++;
  379.       }
  380.   }
  381.   last_node = last;
  382.   va_end(ap);
  383. }
  384.  
  385. wxStringList::~wxStringList(void)
  386. {
  387.   wxNode *each = first_node;
  388.   while (each)
  389.   {
  390.     char *s = (char *)each->Data();
  391.     delete s;
  392.     wxNode *next = each->Next();
  393.     delete each;
  394.     each = next;
  395.   }
  396. }
  397.  
  398. wxNode *wxStringList::Add(char *s)
  399. {
  400.   return Append((wxObject *)(copystring(s)));
  401. }
  402.  
  403. void wxStringList::Delete(char *s)
  404. {
  405.   wxNode *node = First();
  406.   Bool found = FALSE;
  407.   while (node && !found)
  408.   {
  409.     char *string = (char *)node->Data();
  410.     if (strcmp(string, s) == 0)
  411.     {
  412.       found = TRUE;
  413.       delete string;
  414.       delete node;
  415.     }
  416.     else node = node->Next();
  417.   }
  418. }
  419.  
  420. // Only makes new strings if arg is TRUE
  421. char **wxStringList::ListToArray(Bool new_copies)
  422. {
  423.   char **string_array = new char *[Number()];
  424.   wxNode *node = First();
  425.   for (int i = 0; i < n; i++)
  426.   {
  427.     char *s = (char *)node->Data();
  428.     if (new_copies)
  429.       string_array[i] = copystring(s);
  430.     else
  431.       string_array[i] = s;
  432.     node = node->Next();
  433.   }
  434.   return string_array;
  435. }
  436.  
  437. int wx_comparestrings(const void *arg1, const void *arg2)
  438. {
  439.   char **s1 = (char **)arg1;
  440.   char **s2 = (char **)arg2;
  441.  
  442.   return strcmp(*s1, *s2);
  443. }
  444.  
  445. // Sort a list of strings - deallocates old nodes, allocates new
  446. void wxStringList::Sort(void)
  447. {
  448.   int N = n;
  449.   char **array = new char *[N];
  450.   int i = 0;
  451.   wxNode *node = First();
  452.   while (node)
  453.   {
  454.     array[i] = (char *)node->Data();
  455.     i ++;
  456.     node = node->Next();
  457.   }
  458.   qsort(array, N, sizeof(char *), wx_comparestrings);
  459.   Clear();
  460.  
  461.   for (i = 0; i < N; i++)
  462.     Append((wxObject *)(array[i]));
  463.  
  464.   delete array;
  465. }
  466.  
  467. // Checks whether s is a member of the list
  468. Bool wxStringList::Member(char *s)
  469. {
  470.   wxNode *node = First();
  471.   while (node)
  472.   {
  473.     char *s1 = (char *)node->Data();
  474.     if (strcmp(s, s1) == 0)
  475.       return TRUE;
  476.     else node = node->Next();
  477.   }
  478.   return FALSE;
  479. }
  480.