home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / CFGED1B.ZIP / CFGEDSRC.ZIP / STRDLL.CC < prev    next >
C/C++ Source or Header  |  1992-07-18  |  7KB  |  677 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2.  
  3. /* 
  4.  
  5. Copyright (C) 1988 Free Software Foundation
  6.  
  7.     written by Doug Lea (dl@rocky.oswego.edu)
  8.  
  9.  
  10.  
  11. This file is part of the GNU C++ Library.  This library is free
  12.  
  13. software; you can redistribute it and/or modify it under the terms of
  14.  
  15. the GNU Library General Public License as published by the Free
  16.  
  17. Software Foundation; either version 2 of the License, or (at your
  18.  
  19. option) any later version.  This library is distributed in the hope
  20.  
  21. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  22.  
  23. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  24.  
  25. PURPOSE.  See the GNU Library General Public License for more details.
  26.  
  27. You should have received a copy of the GNU Library General Public
  28.  
  29. License along with this library; if not, write to the Free Software
  30.  
  31. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  32.  
  33. */
  34.  
  35.  
  36.  
  37. #ifdef __GNUG__
  38.  
  39. #pragma implementation
  40.  
  41. #endif
  42.  
  43. #include <values.h>
  44.  
  45. #include <stream.h>
  46.  
  47. #include <builtin.h>
  48.  
  49. #include "StrDLL.h"
  50.  
  51.  
  52.  
  53. // error handling
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61. void StrDLList::error(const char* msg)
  62.  
  63. {
  64.  
  65.   (*lib_error_handler)("DLList", msg);
  66.  
  67. }
  68.  
  69.  
  70.  
  71. int StrDLList::length()
  72.  
  73. {
  74.  
  75.   int l = 0;
  76.  
  77.   StrDLListNode* t = h;
  78.  
  79.   if (t != 0) do { ++l; t = t->fd; } while (t != h);
  80.  
  81.   return l;
  82.  
  83. }
  84.  
  85.  
  86.  
  87. StrDLList::StrDLList(StrDLList& a)
  88.  
  89. {
  90.  
  91.   if (a.h == 0)
  92.  
  93.     h = 0;
  94.  
  95.   else
  96.  
  97.   {
  98.  
  99.     StrDLListNode* p = a.h;
  100.  
  101.     StrDLListNode* t = new StrDLListNode(p->hd);
  102.  
  103.     h = t;
  104.  
  105.     p = p->fd;
  106.  
  107.     while (p != a.h)
  108.  
  109.     {
  110.  
  111.       StrDLListNode* n = new StrDLListNode(p->hd);
  112.  
  113.       t->fd = n;
  114.  
  115.       n->bk = t;
  116.  
  117.       t = n;
  118.  
  119.         p = p->fd;
  120.  
  121.     }
  122.  
  123.     t->fd = h;
  124.  
  125.     h->bk = t;
  126.  
  127.     return;
  128.  
  129.   }
  130.  
  131. }
  132.  
  133.  
  134.  
  135. StrDLList& StrDLList::operator = (StrDLList& a)
  136.  
  137. {
  138.  
  139.   if (h != a.h)
  140.  
  141.   {
  142.  
  143.     clear();
  144.  
  145.     if (a.h != 0)
  146.  
  147.     {
  148.  
  149.       StrDLListNode* p = a.h;
  150.  
  151.       StrDLListNode* t = new StrDLListNode(p->hd);
  152.  
  153.       h = t;
  154.  
  155.       p = p->fd;
  156.  
  157.       while (p != a.h)
  158.  
  159.       {
  160.  
  161.         StrDLListNode* n = new StrDLListNode(p->hd);
  162.  
  163.         t->fd = n;
  164.  
  165.         n->bk = t;
  166.  
  167.         t = n;
  168.  
  169.         p = p->fd;
  170.  
  171.       }
  172.  
  173.       t->fd = h;
  174.  
  175.       h->bk = t;
  176.  
  177.     }
  178.  
  179.   }
  180.  
  181.   return *this;
  182.  
  183. }
  184.  
  185.  
  186.  
  187. void StrDLList::clear()
  188.  
  189. {
  190.  
  191.   if (h == 0)
  192.  
  193.     return;
  194.  
  195.  
  196.  
  197.   StrDLListNode* p = h->fd;
  198.  
  199.   h->fd = 0;
  200.  
  201.   h = 0;
  202.  
  203.  
  204.  
  205.   while (p != 0)
  206.  
  207.   {
  208.  
  209.     StrDLListNode* nxt = p->fd;
  210.  
  211.     delete(p);
  212.  
  213.     p = nxt;
  214.  
  215.   }
  216.  
  217. }
  218.  
  219.  
  220.  
  221.  
  222.  
  223. Pix StrDLList::prepend(Str& item)
  224.  
  225. {
  226.  
  227.   StrDLListNode* t = new StrDLListNode(item);
  228.  
  229.   if (h == 0)
  230.  
  231.     t->fd = t->bk = h = t;
  232.  
  233.   else
  234.  
  235.   {
  236.  
  237.     t->fd = h;
  238.  
  239.     t->bk = h->bk;
  240.  
  241.     h->bk->fd = t;
  242.  
  243.     h->bk = t;
  244.  
  245.     h = t;
  246.  
  247.   }
  248.  
  249.   return Pix(t);
  250.  
  251. }
  252.  
  253.  
  254.  
  255. Pix StrDLList::append(Str& item)
  256.  
  257. {
  258.  
  259.   StrDLListNode* t = new StrDLListNode(item);
  260.  
  261.   if (h == 0)
  262.  
  263.     t->fd = t->bk = h = t;
  264.  
  265.   else
  266.  
  267.   {
  268.  
  269.     t->bk = h->bk;
  270.  
  271.     t->bk->fd = t;
  272.  
  273.     t->fd = h;
  274.  
  275.     h->bk = t;
  276.  
  277.   }
  278.  
  279.   return Pix(t);
  280.  
  281. }
  282.  
  283.  
  284.  
  285. Pix StrDLList::ins_after(Pix p, Str& item)
  286.  
  287. {
  288.  
  289.   if (p == 0) return prepend(item);
  290.  
  291.   StrDLListNode* u = (StrDLListNode*) p;
  292.  
  293.   StrDLListNode* t = new StrDLListNode(item, u, u->fd);
  294.  
  295.   u->fd->bk = t;
  296.  
  297.   u->fd = t;
  298.  
  299.   return Pix(t);
  300.  
  301. }
  302.  
  303.  
  304.  
  305. Pix StrDLList::ins_before(Pix p, Str& item)
  306.  
  307. {
  308.  
  309.   if (p == 0) error("null Pix");
  310.  
  311.   StrDLListNode* u = (StrDLListNode*) p;
  312.  
  313.   StrDLListNode* t = new StrDLListNode(item, u->bk, u);
  314.  
  315.   u->bk->fd = t;
  316.  
  317.   u->bk = t;
  318.  
  319.   if (u == h) h = t;
  320.  
  321.   return Pix(t);
  322.  
  323. }
  324.  
  325.  
  326.  
  327. void StrDLList::join(StrDLList& b)
  328.  
  329. {
  330.  
  331.   StrDLListNode* t = b.h;
  332.  
  333.   b.h = 0;
  334.  
  335.   if (h == 0)
  336.  
  337.     h = t;
  338.  
  339.   else if (t != 0)
  340.  
  341.   {
  342.  
  343.     StrDLListNode* l = t->bk;
  344.  
  345.     h->bk->fd = t;
  346.  
  347.     t->bk = h->bk;
  348.  
  349.     h->bk = l;
  350.  
  351.     l->fd = h;
  352.  
  353.   }
  354.  
  355. }
  356.  
  357.  
  358.  
  359. int StrDLList::owns(Pix p)
  360.  
  361. {
  362.  
  363.   StrDLListNode* t = h;
  364.  
  365.   if (t != 0 && p != 0)
  366.  
  367.   {
  368.  
  369.     do
  370.  
  371.     {
  372.  
  373.       if (Pix(t) == p) return 1;
  374.  
  375.       t = t->fd;
  376.  
  377.     } while (t != h);
  378.  
  379.   }
  380.  
  381.   return 0;
  382.  
  383. }
  384.  
  385.  
  386.  
  387. void StrDLList::del(Pix& p, int dir)
  388.  
  389. {
  390.  
  391.   if (p == 0) error("null Pix");
  392.  
  393.   StrDLListNode* t = (StrDLListNode*) p;
  394.  
  395.   if (t->fd == t)
  396.  
  397.   {
  398.  
  399.     h = 0;
  400.  
  401.     p = 0;
  402.  
  403.   }
  404.  
  405.   else
  406.  
  407.   {
  408.  
  409.     if (dir < 0)
  410.  
  411.     {
  412.  
  413.       if (t == h)
  414.  
  415.         p = 0;
  416.  
  417.       else
  418.  
  419.         p = Pix(t->bk);
  420.  
  421.     }
  422.  
  423.     else
  424.  
  425.     {
  426.  
  427.       if (t == h->bk)
  428.  
  429.         p = 0;
  430.  
  431.       else
  432.  
  433.         p = Pix(t->fd);
  434.  
  435.     }
  436.  
  437.     t->bk->fd = t->fd;
  438.  
  439.     t->fd->bk = t->bk;
  440.  
  441.     if (t == h) h = t->fd;
  442.  
  443.   }
  444.  
  445.   delete t;
  446.  
  447. }
  448.  
  449.  
  450.  
  451. void StrDLList::del_after(Pix& p)
  452.  
  453. {
  454.  
  455.   if (p == 0)
  456.  
  457.   {
  458.  
  459.     del_front();
  460.  
  461.     return;
  462.  
  463.   }
  464.  
  465.  
  466.  
  467.   StrDLListNode* b = (StrDLListNode*) p;
  468.  
  469.   StrDLListNode* t = b->fd;
  470.  
  471.  
  472.  
  473.   if (b == t)
  474.  
  475.   {
  476.  
  477.     h = 0;
  478.  
  479.     p = 0;
  480.  
  481.   }
  482.  
  483.   else
  484.  
  485.   {
  486.  
  487.     t->bk->fd = t->fd;
  488.  
  489.     t->fd->bk = t->bk;
  490.  
  491.     if (t == h) h = t->fd;
  492.  
  493.   }
  494.  
  495.   delete t;
  496.  
  497. }
  498.  
  499.  
  500.  
  501. Str StrDLList::remove_front()
  502.  
  503. {
  504.  
  505.   if (h == 0)
  506.  
  507.     error("remove_front of empty list");
  508.  
  509.   StrDLListNode* t = h;
  510.  
  511.   Str res = t->hd;
  512.  
  513.   if (h->fd == h)
  514.  
  515.     h = 0;
  516.  
  517.   else
  518.  
  519.   {
  520.  
  521.     h->fd->bk = h->bk;
  522.  
  523.     h->bk->fd = h->fd;
  524.  
  525.     h = h->fd;
  526.  
  527.   }
  528.  
  529.   delete t;
  530.  
  531.   return res;
  532.  
  533. }
  534.  
  535.  
  536.  
  537.  
  538.  
  539. void StrDLList::del_front()
  540.  
  541. {
  542.  
  543.   if (h == 0)
  544.  
  545.     error("del_front of empty list");
  546.  
  547.   StrDLListNode* t = h;
  548.  
  549.   if (h->fd == h)
  550.  
  551.     h = 0;
  552.  
  553.   else
  554.  
  555.   {
  556.  
  557.     h->fd->bk = h->bk;
  558.  
  559.     h->bk->fd = h->fd;
  560.  
  561.     h = h->fd;
  562.  
  563.   }
  564.  
  565.   delete t;
  566.  
  567. }
  568.  
  569.  
  570.  
  571. Str StrDLList::remove_rear()
  572.  
  573. {
  574.  
  575.   if (h == 0)
  576.  
  577.     error("remove_rear of empty list");
  578.  
  579.   StrDLListNode* t = h->bk;
  580.  
  581.   Str res = t->hd;
  582.  
  583.   if (h->fd == h)
  584.  
  585.     h = 0;
  586.  
  587.   else
  588.  
  589.   {
  590.  
  591.     t->fd->bk = t->bk;
  592.  
  593.     t->bk->fd = t->fd;
  594.  
  595.   }
  596.  
  597.   delete t;
  598.  
  599.   return res;
  600.  
  601. }
  602.  
  603.  
  604.  
  605.  
  606.  
  607. void StrDLList::del_rear()
  608.  
  609. {
  610.  
  611.   if (h == 0)
  612.  
  613.     error("del_rear of empty list");
  614.  
  615.   StrDLListNode* t = h->bk;
  616.  
  617.   if (h->fd == h)
  618.  
  619.     h = 0;
  620.  
  621.   else
  622.  
  623.   {
  624.  
  625.     t->fd->bk = t->bk;
  626.  
  627.     t->bk->fd = t->fd;
  628.  
  629.   }
  630.  
  631.   delete t;
  632.  
  633. }
  634.  
  635.  
  636.  
  637.  
  638.  
  639. int StrDLList::OK()
  640.  
  641. {
  642.  
  643.   int v = 1;
  644.  
  645.   if (h != 0)
  646.  
  647.   {
  648.  
  649.     StrDLListNode* t = h;
  650.  
  651.     long count = MAXLONG;      // Lots of chances to find h!
  652.  
  653.     do
  654.  
  655.     {
  656.  
  657.       count--;
  658.  
  659.       v &= t->bk->fd == t;
  660.  
  661.       v &= t->fd->bk == t;
  662.  
  663.       t = t->fd;
  664.  
  665.     } while (v && count > 0 && t != h);
  666.  
  667.     v &= count > 0;
  668.  
  669.   }
  670.  
  671.   if (!v) error("invariant failure");
  672.  
  673.   return v;
  674.  
  675. }
  676.  
  677.