#include "global.h"
#include "misc.h"
#include "adfile.h"

/***********************************************/

void FreeList(struct AnyNode *List)

{
   struct AnyNode *NextNode;

   while (List)
      {
         NextNode=List->Next;
         FreeVec(List);
         List=NextNode;
      }
}

/***********************************************/

char *FindSlash(char *String)

{
   while (*String && *String!='/') String++;
   return(String);
}

/***********************************************/

BOOL Break(void)

{
   if (SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
      {
         printf("*** User abort.\n");
         return(TRUE);
      }
   return(FALSE);
}

/***********************************************/

void WriteError(char *FormatString, ...)

{
   VPrintf(FormatString,((LONG *)&FormatString)+1);
   if (ErrorFile)
      {
         VFPrintf(ErrorFile,FormatString,((LONG *)&FormatString)+1);
      }
}

/***********************************************/

struct AnyNode **ListToArray(struct AnyNode *List)

{
   int ArrayEntries;
   int Index, Current;
   struct AnyNode *Node;
   struct AnyNode **Array;

   Node=List;
   ArrayEntries=0;
   while (Node)
      {
         ArrayEntries++;
         Node=Node->Next;
      }
   if (Array=AllocVec((ArrayEntries+1)*4,0))
      {
         Array[0]=(struct AnyNode *)ArrayEntries;
         Node=List;
         for (Index=1; Node; Index++)
            {
               Array[Index]=Node;
               Node=Node->Next;
            }
         for (Current=1; Current<ArrayEntries; Current++)
            {
               for (Index=Current+1; Index<=ArrayEntries; Index++)
                  {
                     if (strcmp(Array[Index]->Name,Array[Current]->Name)<0)
                        {
                           Node=Array[Index];
                           Array[Index]=Array[Current];
                           Array[Current]=Node;
                        }
                  }
               if (Break())
                  {
                     FreeVec(Array);
                     return(NULL);
                  }
            }
      }
   else
      {
         PrintFault(ERROR_NO_FREE_STORE,NULL);
      }
   return(Array);
}

/***********************************************/

BOOL ReadLine(BOOL AcceptEOF, BOOL StoreLF)

{
   int Index;
   long Character;

   Index=0;
   while (TRUE)
      {
         if (Break())
            {
               return(FALSE);
            }
         Character=FGetC(CurrentFile);
         switch(Character)
            {
               case -1:     if (IoErr())
                               {
                                  PrintFault(IoErr(),CurrentSource);
                               }
                            else
                               {
                                  if (!AcceptEOF)
                                     {
                                        WriteError("Error: Unexpected end of file %s\n"
                                                   "       Operation aborted.\n",CurrentSource);
                                     }
                               }
                            return(FALSE);

               case '\n':   if (StoreLF)
                               {
                                  Buffer[Index++]='\n';
                               }
                            Buffer[Index]='\0';
                            CurrentLine++;
                            return(TRUE);

               case '\x0c': if (Arguments.CED)
                               {
                                  CurrentLine++;
                               }
                            if (Index)
                               {
                                  WriteError("Error: Unexpected FormFeed in file %s"
                                             "       Operation aborted.\n",CurrentSource);
                                  return(FALSE);
                               }
                            else
                               {
                                  Buffer[0]=Character;
                                  return(TRUE);
                               }

               default:     Buffer[Index++]=Character;
                            if (Index==MAX_LEN)
                               {
                                  WriteError("Error: Line too long in file %s\n"
                                             "       Operation aborted.\n",CurrentSource);
                                  return(FALSE);
                               }
                            break;
            }
      }
}

/***********************************************/

BOOL WriteSomething(char *FormatString, ...)

{
   if (VFPrintf(HypertextFile,FormatString,((LONG *)&FormatString)+1)==-1)
      {
         PrintFault(IoErr(),HypertextFilename);
         return(FALSE);
      }
   return(TRUE);
}

/***********************************************/

void DosError(char *Header)

{
   PrintFault(IoErr(),Header);
   CloseAll();
   exit(10);
}

/***********************************************/

long fgetc(void)

{
   while (TRUE)
      {
         if (Break())
            {
               return(-1);
            }
         if (Buffer[BufferIndex])
            {
               return((long)((unsigned char)(Buffer[BufferIndex++])));
            }
         if (!ReadLine(FALSE,TRUE)) return(-1);
         BufferIndex=0;
      }
}

/***********************************************/

struct AnyNode *SearchNameCase(struct AnyNode **Array, char *Name)

{
   int OldIndex;
   int Upper, Lower;
   int Index;
   int Result;

   Lower=1;
   Upper=(int)Array[0]+1;
   Index=0;
   do
      {
         OldIndex=Index;
         Index=(Upper+Lower)/2;
         if (!(Result=strcmp(Array[Index]->Name,Name)))
            {
               return(Array[Index]);
            }
         if (Result<0)
            {
               Lower=Index;
            }
         else
            {
               Upper=Index;
            }
      }
   while (Index!=OldIndex);
   return(NULL);
}

/***********************************************/

struct AnyNode *SearchNameNoCase(struct AnyNode **Array, char *Name)

{
   int Upper, Lower;
   int Index;
   int OldIndex;
   int Result;

   Lower=1;
   Upper=(int)Array[0]+1;
   Index=0;
   do
      {
         OldIndex=Index;
         Index=(Upper+Lower)/2;
         if (!(Result=Stricmp(Array[Index]->Name,Name)))
            {
               return(Array[Index]);
            }
         if (Result<0)
            {
               Lower=Index;
            }
         else
            {
               Upper=Index;
            }
      }
   while (Index!=OldIndex);
   return(NULL);
}

/***********************************************/

BPTR CreateFile(char *Name)

{
   char *Temp;
   BPTR DirLock;

   Temp=Name;
   while (*Temp)
      {
         if (*Temp=='/')
            {
               *Temp='\0';
               if (!(DirLock=Lock(Name,ACCESS_READ)))
                  {
                     if (!(DirLock=CreateDir(Name)))
                        {
                           *Temp='/';
                           return(NULL);
                        }
                  }
               UnLock(DirLock);
               *Temp='/';
            }
         Temp++;
      }
   return(Open(Name,MODE_NEWFILE));
}
