/*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*\
\                                                                          /
/   Table management                  Copyright (c)  Dmitry A. Kazakov     \
\   [removing]                                       St.Petersburg         /
/   TabDel, TabDelI                                  Autumn, 1993          \
\                                                                          /
/                                                                          \
\   (C, ANSI C)                       Last revision :  18:48 31 Oct 2001   /
/                                                                          \
\   This library is free software; you can redistribute it and/or modify   /
/   it  under  the  terms  of  the GNU Library General Public License as   \
\   published  by  the Free Software Foundation; either version 2 of the   /
/   License, or (at your option) any later version.                        \
\                                                                          /
/   As a special exception, if other  files  instantiate  generics  from   \
\   this unit, or you link this unit with  other  files  to  produce  an   /
/   executable, this  unit  does  not  by  itself  cause  the  resulting   \
\   executable  to  be  covered  by the GNU General Public License. This   /
/   exception  does  not  however  invalidate  any other reasons why the   \
\   executable file might be covered by the GNU Public License.            /
/                                                                          \
\   This library is distributed in the hope that it will be useful,  but   /
/   WITHOUT   ANY   WARRANTY;  without  even  the  implied  warranty  of   \
\   MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE.  See  the  GNU   /
/   Library General Public License for more details.                       \
\                                                                          /
/   You  should  have  received a copy of the GNU Library General Public   \
\   License  along with this library; if not, write to the Free Software   /
/   Foundation,   Inc.,   59  Temple  Place  -  Suite  330,  Boston,  MA   \
\   02111-1307, USA                                                        /
/                                                                          \
\*\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/*/

#include        "tab.h"         /* Table specific               */
/*>

   TabDel -- Delete an item by name

        Table   - Points to table
        Name    - Points to the name of the item to be deleted
        Length  - The name length

   This function deletes an item from table. The item  is  specified  by
   its name.

   Returns :

        [0]  Zero value means successful operation.
        [-]  A negative value is returned if table does not contain  the
             specified  item.  The  value is the negated offset from the
             table  beginning  to  the item whith the greatest name from
             all the items those names are less than the specified one.

<*/
#ifndef NON_ANSI
element TabDel
(
   table        Table, 
   const char * Name,
   const int    Length
)
#else
element TabDel (Table, Name, Length)
   table        Table;
   char *       Name;
   int          Length;
#endif  /*> NON_ANSI <*/
{
   element      Offset = TabFind (Table, Name, Length);

   if (Offset > 0)
   {
      TabDelI (Table, Offset);
      return (0);
   }
   return (Offset);

}       /*>  TabDel  <*/
/*>

   TabDelI -- Delete an item by offset

        Table   -- Points to the table
        Offset  -- The offset of the item to be deleted

   This  function deletes an item from table. It is assumed that TabFind
   was  called  first to determine the offset of the item to be deleted.
   No  checks  are  made,  so  you  should rather use more sophisticated
   function TabDel. 

<*/
#ifndef NON_ANSI
void    TabDelI
(
   table        Table,
   element      Offset
)
#else
void    TabDelI (Table, Offset)
   table        Table;
   element      Offset;
#endif  /*> NON_ANSI <*/
{
   int          Length;
   item         Item;

   Item = (item) ((char *) Table + Offset);
   Length = TAB_NAME_LENGTH (Item);
   if (Length > TAB_EMBEDDED_NAME)
   {
/*>
      Deleted item has the  name  allocated  in  the  table  name  area.
      Therefore  it  is  necessary  to  compress  the  name  area.  This
      operation will change the offsets to the name area for some of the
      TOC items. 
<*/
      char *    NameAreaPtr;
      char *    ItemNamePtr;
      item      TOCItem = (item) TAB_TOC_BEG (Table);
      item      ENDItem = (item) TAB_TOC_END (Table);
      word      ExclNameOffs;

      ExclNameOffs = Item->NameField;
      ItemNamePtr  = TAB_END (Table) - ExclNameOffs;
      NameAreaPtr  = (char *) ENDItem + Table->FreeSpace;
      MvBytes
      (  NameAreaPtr + Length,
         NameAreaPtr,
         ItemNamePtr - NameAreaPtr
      );
/*>
      Here, we must correct the offsets to the name area for all the TOC
      items  those  names  were  allocated after the name of the deleted
      item. For this one should just to diminish the offsets to Length's
      value for each offset that is  greater  than  the  offset  of  the
      deleted item. 
<*/
      for (; TOCItem < ENDItem; TOCItem++)
      {
         if (  TAB_NAME_LENGTH (TOCItem) > TAB_EMBEDDED_NAME
            && ExclNameOffs < TOCItem->NameField
            )  TOCItem->NameField -= Length;
      }
      Table-> FreeSpace += Length;
   }
   MvWords
   (  Item,
      (char *) Item + TAB_ITEM_SIZE,
      Table->TOCSize + sizeof (TabHeader) - TAB_ITEM_SIZE - Offset
   );
   Table->FreeSpace += TAB_ITEM_SIZE;
   Table->TOCSize   -= TAB_ITEM_SIZE;

}       /*>  TableDelI  <*/
