/*
**
** Get inputline from the user.
*/
char *InputLineFromUser()
   {
   extern char InputLine[];

   gets(InputLine);

   return(InputLine);
   }

/*
** This function takes the raw input line *LinePointer and finds the
** end of the processable command, either by the EOL or a ';'.
** *pPointer points to the beginning of the command and *LinePointer
** points to the start of the next command on the same line.
** *LinePointer is set to NULL if the EOL is reached.
** Note that Quote Mode must be processed in such a way that the
** input structure 'this is a ''QUOTE''' translates into "this is a 'QUOTE'".
*/
char *GetCommandLine()
   {
   extern char *LinePointer;
   static char *pPointer;
   BOOL QuoteMode=FALSE, EndOfCommand=FALSE;

   pPointer = LinePointer;         /* Start of Command to be returned */
   while(!EndOfCommand)
      {
      switch(*LinePointer)
         {
         case ';':                  /* Check for Command Seperator */
            if (!QuoteMode)
               {
               *LinePointer='\0';
               EndOfCommand=TRUE;
               }
            ++LinePointer;
            break;
         case '\'':                 /* Check for Quote Mode */
            if (QuoteMode)
               if (*++LinePointer != '\'') QuoteMode = FALSE;
            else
               QuoteMode = TRUE;
            ++LinePointer;
            break;
         case '\0':                /* End of Input Line */
            EndOfCommand=TRUE;
            LinePointer=NULL;
            break;
         default:
            ++LinePointer;
         } /* End Switch */
      }    /* End While  */
   return(pPointer);  /* Return Pointer to Null Terminated Command */
   }

/*
**
** This Function Processes the NULL terminated command line
**
** The first argument must be a VERB, PSEUDOVERB or ADVERB
**
*/
BOOL Process(CommandLine)
char *CommandLine;
   {
   char *StartPointer, *EndPointer, *NextPointer;
   int Index, Count;
   int VerbIndex, PseudoverbIndex, AdverbIndex;

   EndPointer = StartPointer = StripSpaces(CommandLine);
   NextPointer = NULL;
   while(*EndPointer)
      {
      switch (*EndPointer)
         {
         case ' ':
         case '=':
            *EndPointer = '\0';
            NextPointer = EndPointer + 1;
            break;
         Default:
            ++EndPointer;
         }
      }
/*
**
** StartPointer Now Points to the first element that was
** Delimited by either spaces or an equal sign and is
** now NULL terminated.
**
** Test for all the possible elements.
** Index returns the token to the element to direct further
** processing.
**
** NextPointer points to the beginning of the next element to
** be evaluated, or NULL if non is present.
** The element of NextPointer may have spaces or an '=' in front of it.
*/
   Count = 0;
   VerbIndex       = VerbCheck(&Count,StartPointer);
   PseudoverbIndex = PseudoverbCheck(&Count,StartPointer);
   AdverbIndex     = AdverbCheck(&Count,StartPointer);

   if (Count > 1)
      {
      Encode("Ambiguous Command\n");
      DisplayMatchingCommands(StartPointer);
      return(FALSE);
      }

   if (VerbIndex)
      if (ProcessVerb(VerbIndex,NextPointer)) return(FALSE);
   else if (PseudoverbIndex)
      if (ProcessPseudoverb(PseudoverbIndex,NextPointer)) return(FALSE);
   else if (AdverbIndex)
      if (ProcessAdverb(AdverbIndex,NextPointer)) return(FALSE);
   else
      {
      Encode("Unknown Command '%s'\n",StartPointer);
      return(FALSE);
      }

   return(TRUE);
   }

/*
**
** This function returns the VERB index of Pointer, if any
**
*/
int VerbCheck(pCount,cPointer)
int *pCount;
char *cPointer;
   {
   int I, L, Index;
   char VERBS[9];

   L = strlen(cPointer);
   for (I=0;I<Number_of_Verbs;++I)
      {
      LoadString( hMainInst, StartVerbStrings+I, (LPSTR)VERBS, 8);
      if (!strcmpi(cPointer,VERBS))
         {
         *pCount = 1;
         return(I);
         }
      else if (!strnicmp(cPointer,VERBS,L))
         {
         Index = I;
         ++*pCount;
         }
      }
   }

/*
**
** This function returns the PSEUDOVERB index of Pointer, if any
**
*/
int PseudoverbCheck(pCount,cPointer)
int *pCount;
char *cPointer;
   {
   int I, L, Index;
   char PSEUDOVERBS[9];

   L = strlen(cPointer);
   for (I=0;I<Number_of_Pseudoverbs;++I)
      {
      LoadString(hMainInst, StartPseudoverbStrings+I, (LPSTR)PSEUDOVERBS, 8);
      if (!strcmpi(cPointer,PSEUDOVERBS))
         {
         *pCount = 1;
         return(I);
         }
      else if (!strnicmp(cPointer,PSEUDOVERBS,L))
         {
         Index = I;
         ++*pCount;
         }
      }
   }

/*
**
** This function returns the ADVERB index of Pointer, if any
**
*/
int AdverbCheck(pCount,cPointer)
int *pCount;
char *cPointer;
   {
   int I, L, Index;
   char ADVERBS[9];

   L = strlen(cPointer);
   for (I=0;I<Number_of_Adverbs;++I)
      {
      LoadString(hMainInst, StartAdverbStrings+I, (LPSTR)ADVERBS, 8);
      if (!strcmpi(cPointer,ADVERBS))
         {
         *pCount = 1;
         return(I);
         }
      else if (!strnicmp(cPointer,ADVERBS,L))
         {
         Index = I;
         ++*pCount;
         }
      }
   }

/*
**
** This function Display all matching Commands
**
*/
void DisplayMatchingCommands(cPointer)
char *cPointer;
   {
   int I, L, N;
   char String[9];

   N = max(Number_of_Verbs,Number_of_Pseudoverbs);
   N = max(N,Number_of_Adverbs);

   L = strlen(cPointer);

   Encode("Could Be...\n");

   for (I=0;I<N;++I)
      {
      if (I<Number_of_Verbs)
         {
         LoadString(hMainInst, StartVerbStrings+I, (LPSTR)String, 8);
         if (!strnicmp(cPointer,String,L))
            Encode("%s\n",String);
         }
      if (I<Number_of_Pseudoverbs)
         {
         LoadString(hMainInst, StartPseudoverbStrings+I, (LPSTR)String, 8);
         if (!strnicmp(cPointer,String,L))
            Encode("%s\n",String);
         }
      if (I<Number_of_Adverbs)
         {
         LoadString(hMainInst, StartAdverbStrings+I, (LPSTR)String, 8);
         if (!strnicmp(cPointer,String,L))
            Encode("%s\n",String);
         }
      }

   return;
   }

/*
**
** This recursive function returns a structure that holds
** the values of the evaluated expression.
** If the expression returns a string, then Type=1.
** If the expression evaluates to a number, then Type=2.
** If the expression cannot be evaluated, Type = 0;
*/
struct EvalStruct Eval(cPointer)
char *cPointer;
   {
   struct EvalStruct ReturnValue;
   return (ReturnValue);
   }