home *** CD-ROM | disk | FTP | other *** search
/ Meeting Pearls 3 / Meeting_Pearls_III.iso / Pearls / texmf / source / SpecHost / Tools.c < prev    next >
C/C++ Source or Header  |  1995-06-06  |  16KB  |  766 lines

  1. /*
  2. **    SpecialHost for PasTeX
  3. **
  4. **    Copyright © by Olaf Barthel & Georg Heßmann
  5. */
  6.  
  7. /*
  8. ** Tools.c
  9. **
  10. ** Latest revision: 1 Jun 1995, by Giuseppe Ghibò
  11. */
  12.  
  13. #include "Global.h"
  14.  
  15. /* (ghi) BitMapTrack is a useful structure which allows to associate a
  16.    boolean information with a BitMap structure. */
  17.  
  18. struct BitMapTrack {
  19.     struct BitMapTrack *next;
  20.     struct BitMapTrack *prev;
  21.     struct BitMap *bmap;
  22.     BOOL IsAllocBitMapped;
  23. };
  24.  
  25. struct BitMapTrack *bmt = NULL;
  26.  
  27. STATIC VOID __regargs Add_BitMapTrack(struct BitMap *bmap, BOOL status);
  28. STATIC VOID __regargs Del_BitMapTrack(struct BitMap *bmap);
  29. STATIC BOOL __regargs Is_AllocBitMapped(struct BitMap *bmap);
  30. STATIC struct BitMapTrack * __regargs Find_BitMapTrack(struct BitMap *bmap);
  31.  
  32. VOID __regargs
  33. FreeVecPooled(APTR Mem)
  34. {
  35.     if(Mem)
  36.     {
  37.         ULONG *Data = Mem;
  38.  
  39.         LibFreePooled(Pool,&Data[-1],Data[-1]);
  40.     }
  41. }
  42.  
  43. APTR __regargs
  44. AllocVecPooled(LONG Size,ULONG Flags)
  45. {
  46.     if(Size)
  47.     {
  48.         ULONG *Data;
  49.  
  50.         Size += sizeof(ULONG);
  51.  
  52.         if(Data = (ULONG *)LibAllocPooled(Pool,Size))
  53.         {
  54.             *Data++ = Size;
  55.  
  56.             if(Flags & MEMF_CLEAR)
  57.                 memset(Data,0,Size - sizeof(ULONG));
  58.  
  59.             return((APTR)Data);
  60.         }
  61.     }
  62.  
  63.     return(NULL);
  64. }
  65.  
  66. VOID __regargs
  67. ClearList(struct List *List)
  68. {
  69.     struct Node    *Node,
  70.             *Next;
  71.  
  72.     Node = List -> lh_Head;
  73.  
  74.     while(Next = Node -> ln_Succ)
  75.     {
  76.         FreeVecPooled(Node);
  77.  
  78.         Node = Next;
  79.     }
  80.  
  81.     NewList(List);
  82. }
  83.  
  84. struct ListEntry * __regargs
  85. NewEntry(STRPTR Title)
  86. {
  87.     struct ListEntry *Entry;
  88.  
  89.     if(Entry = (struct ListEntry *)AllocVecPooled(sizeof(struct ListEntry) + strlen(Title),MEMF_ANY))
  90.     {
  91.         Entry -> Title = (STRPTR)(Entry + 1);
  92.  
  93.         strcpy(Entry -> Title,Title);
  94.     }
  95.  
  96.     return(Entry);
  97. }
  98.  
  99. WORD __stdargs
  100. ShowRequest(struct Window *Window,STRPTR Text,STRPTR Gadgets,...)
  101. {
  102.     WORD Result;
  103.  
  104.     if(AP_Application)
  105.     {
  106.         va_list VarArgs;
  107.  
  108.         va_start(VarArgs,Gadgets);
  109.         Result = MUI_RequestA(AP_Application,WI_Main,NULL,"SpecialHost",Gadgets,Text,VarArgs);
  110.         va_end(VarArgs);
  111.     }
  112.     else
  113.     {
  114.         struct EasyStruct    Easy;
  115.         ULONG            IDCMP = NULL;
  116.         va_list             VarArgs;
  117.  
  118.         Easy . es_StructSize    = sizeof(struct EasyStruct);
  119.         Easy . es_Flags        = NULL;
  120.         Easy . es_Title        = "SpecialHost";
  121.         Easy . es_TextFormat    = Text;
  122.         Easy . es_GadgetFormat    = Gadgets;
  123.  
  124.         va_start(VarArgs,Gadgets);
  125.         Result = EasyRequestArgs(Window,&Easy,&IDCMP,VarArgs);
  126.         va_end(VarArgs);
  127.     }
  128.  
  129.     return(Result);
  130. }
  131.  
  132. STRPTR __regargs
  133. ShowError(LONG Primary,LONG Secondary,BOOL GetPrimary)
  134. {
  135.     STATIC struct { LONG Code; STRPTR Name; } LocalErrors[] =
  136.     {
  137.         ERR_NO_INTUITION,        "Error opening intuition.library v37",
  138.         ERR_NO_GRAPHICS,        "Error opening graphics.library v37",
  139.         ERR_NO_GADTOOLS,        "Error opening gadtools.library v37",
  140.         ERR_NO_ICON,            "Error opening icon.library v37",
  141.         ERR_NO_IFFPARSE,        "Error opening iffparse.library v37",
  142.         ERR_NO_UTILITY,            "Error opening utility.library v37",
  143.         ERR_NO_ASL,            "Error opening asl.library v37",
  144.         ERR_NO_MUI,            "Error opening muimaster.library",
  145.         ERR_NO_MATHFFP,            "Error opening mathieeedoubbas.library",
  146.         ERR_NO_MATHTRANS,        "Error opening mathieeedoubtrans.library",
  147.         ERR_NO_POOL,            "Error creating memory pool",
  148.         ERR_NO_GUI,            "Error opening window",
  149.         ERR_ALREADY_RUNNING,        "SpecialHost process already running",
  150.         ERR_NO_PORT,            "Error opening message port",
  151.         ERR_READ_ERROR,            "Error reading file",
  152.         ERR_NO_MEM,            "Out of memory",
  153.         ERR_FILE_FORMAT_ERROR,        "File format corrupt",
  154.         ERR_WEIRD_COMPRESSION,        "Image compression type not supported",
  155.         ERR_WRONG_IMAGE_FORMAT,        "Cannot handle picture file format",
  156.         ERR_TOO_LARGE,            "Requested image size is too large",
  157.         ERR_TOO_SMALL,            "Requested image size is too small",
  158.         ERR_NO_NIL,            "Error opening NIL: stream",
  159.         ERR_NO_POST,            "Error opening post.library v15",
  160.  
  161.         DTERROR_UNKNOWN_DATATYPE,    "Unknown file format",
  162.         DTERROR_COULDNT_SAVE,        "Could not store file",
  163.         DTERROR_COULDNT_OPEN,        "Could not open file",
  164.         DTERROR_COULDNT_SEND_MESSAGE,    "Internal send message error",
  165.         DTERROR_COULDNT_OPEN_CLIPBOARD,    "Could not open clipboard",
  166.         DTERROR_UNKNOWN_COMPRESSION,    "Compression method unknown",
  167.         DTERROR_NOT_ENOUGH_DATA,    "Not enough data available",
  168.         DTERROR_INVALID_DATA,        "Invalid data",
  169.  
  170.         19999,                "Postscript error: File not found",
  171.         20001,                "Postscript error: Dictionary full",
  172.         20002,                "Postscript error: Dictionary stack overflow",
  173.         20003,                "Postscript error: Dictionary stack underflow",
  174.         20004,                "Postscript error: Exec stack overflow",
  175.         20005,                "Postscript error: Interrupted",
  176.         20006,                "Postscript error: Invalid access",
  177.         20007,                "Postscript error: Invalid exit",
  178.         20008,                "Postscript error: Invalid file access",
  179.         20009,                "Postscript error: Invalid font",
  180.         20010,                "Postscript error: Invalid restore",
  181.         20011,                "Postscript error: Invalid stop",
  182.         20012,                "Postscript error: I/O error",
  183.         20013,                "Postscript error: Limit check trap",
  184.         20014,                "Postscript error: No current point",
  185.         20015,                "Postscript error: Range check trap",
  186.         20016,                "Postscript error: Stack overflow",
  187.         20017,                "Postscript error: Stack underflow",
  188.         20018,                "Postscript error: Syntax error",
  189.         20019,                "Postscript error: Timeout",
  190.         20020,                "Postscript error: Typecheck",
  191.         20021,                "Postscript error: Undefined",
  192.         20022,                "Postscript error: Undefined filename",
  193.         20023,                "Postscript error: Undefined result",
  194.         20024,                "Postscript error: Unmatched mark",
  195.         20025,                "Postscript error: Unregistered",
  196.         20026,                "Postscript error: Virtual memory error",
  197.         20027,                "Postscript error: Memory allocation error",
  198.         20028,                "Postscript error: Killed",
  199.         20029,                "Postscript error: Configuration",
  200.         20030,                "Postscript error: Undefined resource",
  201.  
  202.         IFFERR_NOMEM,            "Out of memory",
  203.         IFFERR_READ,            "File read error",
  204.         IFFERR_WRITE,            "File write error",
  205.         IFFERR_SEEK,            "File seek error",
  206.         IFFERR_MANGLED,            "File structure damaged",
  207.         IFFERR_NOTIFF,            "Not an IFF format file",
  208.  
  209.         0,                NULL
  210.     };
  211.  
  212.     STRPTR    PrimaryError    = NULL,
  213.         SecondaryError    = NULL;
  214.  
  215.     if(Primary)
  216.     {
  217.         LONG i;
  218.  
  219.         for(i = 0 ; LocalErrors[i] . Name ; i++)
  220.         {
  221.             if(LocalErrors[i] . Code == Primary)
  222.             {
  223.                 PrimaryError = LocalErrors[i] . Name;
  224.  
  225.                 break;
  226.             }
  227.         }
  228.  
  229.         if(!PrimaryError)
  230.         {
  231.             STATIC UBYTE __far Buffer[256];
  232.  
  233.             Fault(Primary,"",Buffer,256);
  234.  
  235.             PrimaryError = Buffer + 2;
  236.         }
  237.  
  238.         if(GetPrimary)
  239.             return(PrimaryError);
  240.     }
  241.  
  242.     if(Secondary)
  243.     {
  244.         LONG i;
  245.  
  246.         for(i = 0 ; LocalErrors[i] . Name ; i++)
  247.         {
  248.             if(LocalErrors[i] . Code == Secondary)
  249.             {
  250.                 SecondaryError = LocalErrors[i] . Name;
  251.  
  252.                 break;
  253.             }
  254.         }
  255.  
  256.         if(!SecondaryError)
  257.         {
  258.             STATIC UBYTE __far Buffer[256];
  259.  
  260.             Fault(Secondary,"",Buffer,256);
  261.  
  262.             SecondaryError = Buffer + 2;
  263.         }
  264.     }
  265.  
  266.     if(PrimaryError)
  267.     {
  268.         if(ThisProcess -> pr_CLI)
  269.         {
  270.             if(SecondaryError)
  271.                 Printf("SpecialHost: %s, %s\a\n",PrimaryError,SecondaryError);
  272.             else
  273.                 Printf("SpecialHost: %s\a\n",PrimaryError);
  274.         }
  275.         else
  276.         {
  277.             if(IntuitionBase)
  278.             {
  279.                 if(SecondaryError)
  280.                     ShowRequest(NULL,"%s\n%s","Continue",PrimaryError,SecondaryError);
  281.                 else
  282.                     ShowRequest(NULL,"%s","Continue",PrimaryError);
  283.             }
  284.         }
  285.     }
  286. }
  287.  
  288. VOID __regargs
  289. DeleteBitMap(struct BitMap *BitMap)
  290. {
  291.     if(GfxBase -> LibNode . lib_Version >= 39 && Is_AllocBitMapped(BitMap))
  292.     {
  293.         Del_BitMapTrack(BitMap);
  294.  
  295.         if (BitMap)
  296.             FreeBitMap(BitMap);
  297.     }
  298.     else
  299.     {
  300.         if (BitMap)
  301.         {
  302.             LONG i;
  303.  
  304.             for(i = 0; i < BitMap -> Depth; i++)
  305.             {
  306.                 if(BitMap -> Planes[i])
  307.                     FreeVec(BitMap -> Planes[i]);
  308.             }
  309.             FreeVecPooled(BitMap);
  310.         }
  311.     }
  312. }
  313.  
  314. struct BitMap * __regargs
  315. CreateBitMap(LONG Width,LONG Height,LONG Depth,ULONG Flags,struct BitMap *Friend)
  316. {
  317.  
  318.     if(GfxBase -> LibNode . lib_Version < 39 || (Flags & BMAP_MEMF_ANY))
  319.     {
  320.  
  321.     /* Code used for OS 2.1 (and for OS 3.0 if Flags contains BMAP_MEMF_ANY) */
  322.  
  323.         struct BitMap    *BitMap;
  324.         LONG         Plus;
  325.  
  326.         Width = (Width + 15) & ~15; /* (ghi) fixed for OS 2.1, word alignment */
  327.  
  328.         if(Depth > 8)
  329.             Plus = (Depth - 8) * sizeof(PLANEPTR);
  330.         else
  331.             Plus = 0;
  332.  
  333.         if(BitMap = (struct BitMap *)AllocVecPooled(sizeof(struct BitMap) + Plus,MEMF_ANY | MEMF_CLEAR))
  334.         {
  335.             LONG i,PageSize;
  336.  
  337.             InitBitMap(BitMap,Depth,Width,Height);
  338.  
  339.             PageSize = BitMap -> BytesPerRow * BitMap -> Rows;
  340.  
  341.             for(i = 0 ; i < BitMap -> Depth ; i++)
  342.             {
  343.                 if (Flags & BMAP_MEMF_ANY)
  344.                     BitMap -> Planes[i] = (PLANEPTR)AllocVec(PageSize,MEMF_ANY | ((Flags & BMF_CLEAR) ? MEMF_CLEAR : 0));
  345.                 else
  346.                     BitMap -> Planes[i] = (PLANEPTR)AllocVec(PageSize,MEMF_CHIP);
  347.  
  348.                 if(!BitMap -> Planes[i])
  349.                 {
  350.                     LONG j;
  351.  
  352.                     for(j = 0 ; j < i ; j++)
  353.                         FreeVec(BitMap -> Planes[j]);
  354.  
  355.                     FreeVecPooled(BitMap);
  356.  
  357.                     return(NULL);
  358.                 }
  359.             }
  360.  
  361.             if((Flags & BMF_CLEAR) && !(Flags & BMAP_MEMF_ANY))
  362.             {
  363.                 for (i = 0; i < BitMap -> Depth ; i++)
  364.                 {
  365.                     if (TypeOfMem(BitMap->Planes[0]) & MEMF_CHIP)
  366.                         BltBitMap(BitMap,0,0,BitMap,0,0,Width,Height,0x00,(1 << Depth) - 1,NULL);
  367.                     else
  368.                         memset(BitMap -> Planes[i], 0, PageSize);
  369.                 }
  370.             }
  371.  
  372. //            Printf("BitMap Address = $%lx [MEMF_%s] %s\n",BitMap -> Planes[0], (TypeOfMem(BitMap -> Planes[0]) & MEMF_CHIP ? "CHIP" : "FAST"), ((Flags & BMAP_MEMF_ANY) ? "(BMAP_MEMF_ANY)" : ""));
  373.             return(BitMap);
  374.         }
  375.     }
  376.     else
  377.     {
  378.         struct BitMap *BitMap = AllocBitMap(Width,Height,Depth,Flags,Friend); /* OS 3.0 */
  379.     
  380.         if (BitMap)
  381.             Add_BitMapTrack(BitMap, TRUE); /* (ghi) to keep track that memory was allocated by AllocBitMap() and need to be freed by FreeBitMap() */
  382.  
  383.         return (BitMap);
  384.     }
  385. }
  386.  
  387. VOID __regargs
  388. DeleteTempLine(UBYTE *Line)
  389. {
  390.     FreeVecPooled(Line);
  391. }
  392.  
  393. UBYTE * __regargs
  394. CreateTempLine(LONG Width,LONG Height)
  395. {
  396.     return((UBYTE *)AllocVecPooled(((Width + 15) & ~15) * Height,MEMF_ANY));
  397. }
  398.  
  399. VOID __regargs
  400. DeleteTempRPort(struct RastPort *Temp)
  401. {
  402.     DeleteBitMap(Temp -> BitMap);
  403.  
  404.     FreeVecPooled(Temp);
  405. }
  406.  
  407. struct RastPort * __regargs
  408. CreateTempRPort(struct RastPort *Source)
  409. {
  410.     struct RastPort *Temp;
  411.  
  412.     if(Temp = (struct RastPort *)AllocVecPooled(sizeof(struct RastPort),MEMF_ANY))
  413.     {
  414.         LONG Width,Depth;
  415.  
  416.         CopyMem(Source,Temp,sizeof(struct RastPort));
  417.  
  418.         Temp -> Layer = NULL;
  419.  
  420.         if(GfxBase -> LibNode . lib_Version < 39)
  421.         {
  422.             Width    = Source -> BitMap -> BytesPerRow * 8;
  423.             Depth    = Source -> BitMap -> Depth;
  424.         }
  425.         else
  426.         {
  427.             Width    = GetBitMapAttr(Source -> BitMap,BMA_WIDTH);
  428.             Depth    = GetBitMapAttr(Source -> BitMap,BMA_DEPTH);
  429.         }
  430.  
  431.         if(Temp -> BitMap = CreateBitMap(Width,1,Depth,NULL,Source -> BitMap))
  432.             return(Temp);
  433.         else
  434.             FreeVecPooled(Temp);
  435.     }
  436.  
  437.     return(NULL);
  438. }
  439.  
  440. LONG __regargs
  441. FileDateCheck(STRPTR File1,STRPTR File2,LONG *Error)
  442. {
  443.     struct FileInfoBlock    *FileInfo;
  444.     LONG             Result = 0;
  445.  
  446.     *Error = 0;
  447.  
  448.     if(FileInfo = (struct FileInfoBlock *)AllocDosObjectTags(DOS_FIB,TAG_DONE))
  449.     {
  450.         BPTR FileLock;
  451.  
  452.         if(FileLock = Lock(File1,ACCESS_READ))
  453.         {
  454.             if(Examine(FileLock,FileInfo))
  455.             {
  456.                 struct DateStamp Date1;
  457.  
  458.                 Date1 = FileInfo -> fib_Date;
  459.  
  460.                 UnLock(FileLock);
  461.  
  462.                 if(FileLock = Lock(File2,ACCESS_READ))
  463.                 {
  464.                     if(Examine(FileLock,FileInfo))
  465.                     {
  466.                         struct DateStamp Date2;
  467.  
  468.                         Date2 = FileInfo -> fib_Date;
  469.  
  470.                         Result = CompareDates(&Date1,&Date2);
  471.                     }
  472.                     else
  473.                         *Error = IoErr();
  474.                 }
  475.                 else
  476.                     *Error = IoErr();
  477.             }
  478.             else
  479.                 *Error = IoErr();
  480.  
  481.             if(FileLock)
  482.                 UnLock(FileLock);
  483.         }
  484.         else
  485.             *Error = IoErr();
  486.  
  487.         FreeDosObject(DOS_FIB,FileInfo);
  488.     }
  489.     else
  490.         *Error = ERR_NO_MEM;
  491.  
  492.     return(Result);
  493. }
  494.  
  495. VOID __regargs
  496. AddProtection(STRPTR Name,ULONG Mask)
  497. {
  498.     struct FileInfoBlock *FileInfo;
  499.  
  500.     if(FileInfo = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,TAG_DONE))
  501.     {
  502.         BPTR FileLock;
  503.  
  504.         if(FileLock = Lock(Name,ACCESS_READ))
  505.         {
  506.             if(Examine(FileLock,FileInfo))
  507.             {
  508.                 UnLock(FileLock);
  509.  
  510.                 SetProtection(Name,FileInfo -> fib_Protection | Mask);
  511.             }
  512.             else
  513.                 UnLock(FileLock);
  514.         }
  515.  
  516.         FreeDosObject(DOS_FIB,FileInfo);
  517.     }
  518. }
  519.  
  520. STATIC LONG    MaxProgress    = 1,
  521.         LastProgress    = -1;
  522.  
  523. VOID __regargs
  524. SetMaxProgress(LONG Count)
  525. {
  526.     if(GA_Gauge)
  527.     {
  528.         SetAttrs(GA_Gauge,
  529.             MUIA_Gauge_Current,    0,
  530.             MUIA_Gauge_Max,        Count,
  531.         TAG_DONE);
  532.     }
  533.     else
  534.     {
  535.         if(LastProgress != 100 && LastProgress != -1)
  536.             FPrintf(ThisProcess -> pr_COS,"\n");
  537.  
  538.         FPrintf(ThisProcess -> pr_COS,"\33[0 pWorking:   0%");
  539.         Flush(ThisProcess -> pr_COS);
  540.  
  541.         MaxProgress    = Count;
  542.         LastProgress    = 0;
  543.     }
  544. }
  545.  
  546. VOID __regargs
  547. ShowProgress(LONG Count)
  548. {
  549.     if(GA_Gauge)
  550.         set(GA_Gauge,MUIA_Gauge_Current,Count);
  551.     else
  552.     {
  553.         if(ThisProcess -> pr_CLI)
  554.         {
  555.             Count = (100 * Count) / MaxProgress;
  556.  
  557.             if(Count < 0)
  558.                 Count = 0;
  559.             else
  560.             {
  561.                 if(Count > 100)
  562.                     Count = 100;
  563.             }
  564.  
  565.             if(LastProgress != Count)
  566.             {
  567.                 FPrintf(ThisProcess -> pr_COS,"\33[4D%3ld%%",Count);
  568.  
  569.                 Flush(ThisProcess -> pr_COS);
  570.  
  571.                 LastProgress = Count;
  572.  
  573.                 if(LastProgress == 100)
  574.                 {
  575.                     FPrintf(ThisProcess -> pr_COS,"\n\33[ p");
  576.  
  577.                     Flush(ThisProcess -> pr_COS);
  578.                 }
  579.             }
  580.         }
  581.     }
  582. }
  583.  
  584. LONG __regargs
  585. GetMapCode(struct MapTable *Table,STRPTR Key)
  586. {
  587.     while(Table -> Key)
  588.     {
  589.         if(!Stricmp(Table -> Key,Key))
  590.             return(Table -> ID);
  591.         else
  592.             Table++;
  593.     }
  594.  
  595.     return(-1);
  596. }
  597.  
  598.  
  599. /* (ghi) InvertBitMap() inverts a BitMap in any memory (even FAST);
  600.    Width and Height are the respectively the width and the height of
  601.    the area to invert. These values may be less or equal of the true
  602.    BitMap sizes. */
  603.  
  604. VOID __regargs InvertBitMap(struct BitMap *BitMap, LONG Width, LONG Height)
  605. {
  606.     if (TypeOfMem(BitMap -> Planes[0]) & MEMF_CHIP)
  607.         BltBitMap(BitMap,0,0,BitMap,0,0,Width,Height,0x50,1,NULL);
  608.     else
  609.     {
  610.         UWORD *p;
  611.         LONG i,j,k;
  612.  
  613.         if (Width > (BitMap -> BytesPerRow << 3))
  614.             Width = BitMap -> BytesPerRow << 3;
  615.  
  616.         if (Height > BitMap -> Rows)
  617.             Height = BitMap -> Rows;
  618.  
  619.         for (i=0; i < BitMap -> Depth; i++)
  620.         {
  621.             p = (UWORD *) BitMap -> Planes[i];
  622.             for (j = 0; j < Height; j++)
  623.             {
  624.                 for (k = 0; k < (Width >> 4); k++)
  625.                 {
  626.                     p[k] = ~p[k];
  627.                 }
  628.                 p += BitMap -> BytesPerRow >> 1;
  629.             }
  630.         }
  631.  
  632.         k = Width % 16;
  633.         if (k > 0)
  634.         {
  635.             UWORD mask = ((1 << k) - 1) << 16 - k;
  636.             for (i=0; i < BitMap -> Depth; i++)
  637.             {
  638.                 p = (UWORD *) BitMap -> Planes[i];
  639.                 for (j = 0; j < Height; j++)
  640.                 {
  641.                     p[Width >> 4] ^= mask;
  642.                     p += BitMap -> BytesPerRow >> 1;
  643.                 }
  644.             }
  645.         }    
  646.     }
  647. }
  648.  
  649. /* (ghi) Here follow some functions to keep track if a BitMap was allocated
  650.    by AllocBitMap() or by AllocVec(). These functions are
  651.    Add_BitMapTrack(), Del_BitMapTrack, Find_BitMapTrack() and
  652.    IsAllocBitMapped(). */
  653.  
  654. STATIC VOID __regargs Add_BitMapTrack(struct BitMap *bmap, BOOL status)
  655. {
  656.     if (bmap == NULL)
  657.         return;
  658.  
  659.     if (bmt == NULL) /* A NULL bmt indicates an empty list */
  660.     { 
  661.         if (bmt = AllocVecPooled(sizeof(struct BitMapTrack), MEMF_ANY | MEMF_CLEAR))
  662.         {
  663.             bmt -> next = bmt -> prev = NULL;
  664.             bmt -> bmap = bmap;
  665.             bmt -> IsAllocBitMapped = status;
  666.         }
  667.         else
  668.             return;
  669.     }
  670.     else
  671.     {
  672.         while (bmt -> next)
  673.                 bmt = bmt -> next; /* seek bmt to the last node */
  674.  
  675.         if (bmt -> next = AllocVecPooled(sizeof(struct BitMapTrack), MEMF_ANY | MEMF_CLEAR))
  676.         {
  677.             bmt -> next -> prev = bmt;
  678.             bmt = bmt -> next; /* Link to next node */
  679.             bmt -> next = NULL; /* last note */
  680.             bmt -> bmap = bmap;
  681.             bmt -> IsAllocBitMapped = status;
  682.         }
  683.         else
  684.             return;
  685.     }
  686. }
  687.  
  688. STATIC BOOL __regargs Is_AllocBitMapped(struct BitMap *bmap)
  689. {
  690.     struct BitMapTrack *p;
  691.  
  692.     if (p = Find_BitMapTrack(bmap))
  693.         return (p -> IsAllocBitMapped);
  694.     else
  695.         return (FALSE);
  696. }
  697.  
  698. STATIC struct BitMapTrack * __regargs Find_BitMapTrack(struct BitMap *bmap)
  699. {
  700.     struct BitMapTrack *p = bmt;
  701.  
  702.     if (!p)
  703.         return NULL;    /* (hes) */
  704.  
  705.     do
  706.     {
  707.         if (p -> bmap == bmap)
  708.             return (p);
  709.     } 
  710.     while (p = p -> prev); /* scan backward */
  711.  
  712.     if (p = bmt -> next)
  713.     {
  714.         do
  715.         {
  716.             if (p -> bmap == bmap)
  717.                 return (p);
  718.         }
  719.         while (p = p -> next); /* scan forward */
  720.     }
  721.  
  722.     return (NULL); /* not found */
  723. }
  724.  
  725. STATIC VOID __regargs Del_BitMapTrack(struct BitMap *bmap)
  726. {
  727.     struct BitMapTrack *p = Find_BitMapTrack(bmap);
  728.  
  729.     if (!p)
  730.         return;
  731.  
  732.         if (p -> next && p -> prev) /* p is a mid node */
  733.     {
  734.         p -> prev -> next = p -> next;
  735.         p -> next -> prev = p -> prev;
  736.  
  737.         if (bmt == p)
  738.             bmt = p -> next;
  739.  
  740.         FreeVecPooled(p);
  741.     }
  742.     else if (p -> next) /* there are no more nodes before p (p is the first node) */
  743.     {
  744.         p -> next -> prev = NULL; /* new first node */
  745.  
  746.         if (bmt == p)
  747.             bmt = p -> next;
  748.  
  749.         FreeVecPooled(p);
  750.     }
  751.     else if (p -> prev) /* there are no more nodes after p (p is the last node) */
  752.     {
  753.         p -> prev -> next = NULL; /* new last node */
  754.  
  755.         if (bmt == p)
  756.             bmt = p -> prev;
  757.  
  758.         FreeVecPooled(p);
  759.     }
  760.     else /* there are no more nodes after nor before p (p is the only node) */
  761.     {
  762.         FreeVecPooled(p);
  763.         bmt = NULL;
  764.     }
  765. }
  766.