/*********************************************/
/* File -Func.c- contains FHBCPP functions   */
/*********************************************/
/*5696-737 (C) COPYRIGHT IBM CORP. 1988-94   */
/*LICENSED MATERIAL - PROGRAM PROPERTY OF IBM*/
/*********************************************/


#ifdef __NT__
#include <io.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "fhbcpp.h"


/***********************************/
/***** Begin helping functions *****/
/***********************************/

/* Returns index position of -msg in -string- (first index = 1) */
/* Returns 0 if not found */
int getindex(char *string, char *msg)
{
   if (strstr(string, msg) == NULL)
      return 0;
   else
      return (strstr(string, msg) - string) + INDEX_CONSTANT;
}

/* Converts a character to a string */
char *char2str(char chr)
{
   static char buffer[2];

   buffer[0] = chr;
   buffer[1] = 0;

   return buffer;
}

/* Returns character at -pos- (first index = 1) */
char subchar(char *string, int pos)
{
   return string[pos-INDEX_CONSTANT];
}

/* Returns substring at -start- (first index = 1) */
char *substr(char *string, int start, int length)
{
   static char buffer[300];

   strncpy(buffer, &string[start-INDEX_CONSTANT], length);
   buffer[length] = 0;

   return buffer;
}

/* Returns TRUE if substring of -string- has -msg- value at -pos- */
int subcmp(char *string, char *msg, int pos)
{
   int length = strlen(msg);

   if (strncmp(substr(string, pos, length), msg, length) == 0)
      return TRUE;
   else
      return FALSE;
}

/* Returns TRUE if subchar of -string- has -chr- value at -pos- */
int subcmpc(char *string, char chr, int pos)
{
   if (strncmp(substr(string, pos, 1), char2str(chr), 1) == 0)
      return TRUE;
   else
      return FALSE;
}

/***********************************/
/***** End helping Functions   *****/
/***********************************/



/***************************************/
/***** Begin FHBCPP PLI Functions  *****/
/***************************************/

/***********************************************/
/** mss: proc(infilerec,scanchar,scanpos);    **/
/***********************************************/
/* Comments: Scan string                       */
/***********************************************/
/* External variables: None                    */
/***********************************************/
void mss(char *infilerec, char scanchar, int *scanpos)
{
   (*scanpos)++;

   while (*scanpos <= 72 &&
          (!subcmpc(infilerec, scanchar, *scanpos) ||
           (*scanpos < 72 && subcmpc(infilerec, scanchar, *scanpos+1))
          )
         )
      if (subcmpc(infilerec, scanchar, *scanpos))
         *scanpos += 2;
      else
         (*scanpos)++;

   (*scanpos)++;
}


/***********************************************/
/** mclfc: proc(infilerec,copypos) recursive; **/
/***********************************************/
/* Comments: Check line for 'COPY'             */
/***********************************************/
/* External variables: None                    */
/***********************************************/
void mclfc(char *infilerec, int *copypos)
{
   int check_string;

   if (subcmp(infilerec, " ", 7) ||
       subcmp(infilerec, "-", 7))
   {
      check_string = FALSE;
      *copypos = getindex(infilerec, " COPY ");

      if (*copypos == 0)
      {
         if (subcmp(infilerec, "DCOPY ", 7))
            *copypos = 8;
         else
            if (subcmp(infilerec, " COPY", 68))
            {
               *copypos = 69;
               check_string = TRUE;
            }
      }
      else
      {
         (*copypos)++;
         check_string = TRUE;
      }

      if (check_string)
      {
         int scanpos = 8, in_string = FALSE;
         char pdfilerec[80];

         do
         {
            while (scanpos < *copypos &&
                   !subcmp(infilerec, "'",  scanpos) &&
                   !subcmp(infilerec, "\"", scanpos))
               scanpos++;

            if (scanpos < *copypos)
            {
               /* FHB function call */
               mss(infilerec, subchar(infilerec, scanpos), &scanpos);

               if (scanpos > *copypos)
                  in_string = TRUE;
            }
         }
            while (!(scanpos >= *copypos));

         if (in_string)
         {
            strcpy(pdfilerec, substr(BLANKS80, 1, scanpos-1));
            strcat(pdfilerec, substr(infilerec, scanpos, 1));

            /* FHB function call (recursive) */
            mclfc(pdfilerec, copypos);
         }
      }
   }
   else
      *copypos = 0;
}


/***********************************************/
/** msi: proc(infilerec,scanchar,scanpos);    **/
/***********************************************/
/* Comments: Scan string                       */
/***********************************************/
/* External variables: None                    */
/***********************************************/
void msi(char *infilerec, char scanchar, int *scanpos)
{
   /* C Optimization */
   mss(infilerec, scanchar, scanpos);
}


/***********************************************/
/** mclfi: proc(infilerec,inclpos) recursive; **/
/***********************************************/
/* Comments: Check line for 'INCLUDE'          */
/***********************************************/
/* External variables: None                    */
/***********************************************/
void mclfi(char* infilerec, int *inclpos)
{
   int check_string;

   if (subcmp(infilerec, " ", 7) ||
       subcmp(infilerec, "-", 7))
   {
      check_string = FALSE;
      *inclpos = getindex(infilerec, " INCLUDE ");

      if (*inclpos == 0)
      {
         if (subcmp(infilerec, "DINCLUDE ", 7))
            *inclpos = 8;
         else
            if (subcmp(infilerec, " INCLUDE", 65))
            {
               *inclpos = 66;
               check_string = TRUE;
            }
      }
      else
      {
         (*inclpos)++;
         check_string = TRUE;
      }

      if (check_string)
      {
         int scanpos = 8, in_string = FALSE;
         char pdfilerec[80];

         do
         {
            while (scanpos < *inclpos &&
                   !subcmp(infilerec, "'",  scanpos) &&
                   !subcmp(infilerec, "\"", scanpos))
               scanpos++;

            if (scanpos < *inclpos)
            {
               /* FHB function call */
               msi(infilerec, subchar(infilerec, scanpos), &scanpos);

               if (scanpos > *inclpos)
                  in_string = TRUE;
            }
         }
            while (!(scanpos >= *inclpos));

         if (in_string)
         {
            strcpy(pdfilerec, substr(BLANKS80, 1, scanpos-1));
            strcat(pdfilerec, substr(infilerec, scanpos, 1));

            /* FHB function call (recursive) */
            mclfi(pdfilerec, inclpos);
         }
      }
   }
   else
      *inclpos = 0;
}

/***************************************/
/***** End FHBCPP PLI Functions    *****/
/***************************************/



/***********************************************/
/** do_mspq: PLI included code                **/
/***********************************************/
/* Comments: Scan past qualifier               */
/***********************************************/
/* External variables: Outfile                 */
/***********************************************/
void do_mspq(char *infilerec, int *scanpos)
{
   int sp, endpos;
   char scanchar;

   sp = *scanpos;
   scanchar = subchar(infilerec, sp);

   while (sp <= 72 &&
          (scanchar == ' ' || scanchar == ',' || scanchar == ';'))
   {
      sp++;
      scanchar = subchar(infilerec, sp);
   }

   if (sp < 72)
   {
      endpos = sp;

      while (endpos <= 72 && scanchar != ' ' && scanchar != ',' &&
             scanchar != ';' && scanchar != '.')
      {
         endpos++;
         scanchar = subchar(infilerec, endpos);
      }

      if (subcmp(infilerec, "OF", sp) ||
          subcmp(infilerec, "IN", sp))
      {
         *scanpos = endpos;

         /* Scan past library name */
         scanchar = subchar(infilerec, *scanpos);

         while (*scanpos <= 72 &&
                (scanchar == ' ' || scanchar == ',' || scanchar ==';'))
         {
            (*scanpos)++;
            scanchar = subchar(infilerec, *scanpos);
         }
         while (*scanpos <= 72 && scanchar != ' ' && scanchar != ',' &&
                scanchar != ';' && scanchar != '.')
         {
            (*scanpos)++;
            scanchar = subchar(infilerec, *scanpos);
         }

         /* Scan past 'SUPPRESS' */
         {
            int sp, endpos;
            char scanchar;

            sp = *scanpos;
            scanchar = subchar(infilerec, sp);

            while (sp <= 72 &&
                   (scanchar == ' ' || scanchar == ',' || scanchar ==';'))
            {
               sp++;
               scanchar = subchar(infilerec, sp);
            }

            endpos = sp;

            while (*scanpos <= 72 && scanchar != ' ' && scanchar != ',' &&
                   scanchar != ';' && scanchar != '.')
            {
               (*scanpos)++;
               scanchar = subchar(infilerec, *scanpos);
            }

            if (sp <= 72 && subcmp(infilerec, "SUPPRESS", sp))
               *scanpos = endpos;
         }
      }
      else
         if (subcmp(infilerec, "SUPPRESS", sp))
            *scanpos = endpos;
   }
}


/***********************************************/
/** do_mfmn: PLI included code                **/
/***********************************************/
/* Comments: Find member name                  */
/***********************************************/
/* External variables: Outfile                 */
/***********************************************/
void do_mfmn(char *infilerec, char *member, int *scanpos, char *extstr)
{
   int scandone, found_period;
   char scanchar, member_string[80],
        cpfilerec[80], /*check_string[80]*/
        line[100];

   scanchar = subchar(infilerec, *scanpos);

   while (*scanpos <= 72 &&
          (scanchar == ' ' || scanchar == ',' || scanchar == ';'))
   {
      (*scanpos)++;
      scanchar = subchar(infilerec, *scanpos);
   }

   strcpy(member_string, "");
   scandone = (*scanpos > 72);

   while (!scandone)
   {
      strcat(member_string, char2str(scanchar));
      (*scanpos)++;
      scanchar = subchar(infilerec, *scanpos);

      /* Remove the period from the following test... */
      scandone = (*scanpos > 72 || scanchar == ' ' ||
                  scanchar == ',' || scanchar == ';');
   }

   if (!member_string[0])
      strcpy(member_string, " ");
   else
   {
      if (subcmp(member_string, "'", 1) ||
          subcmp(member_string, "\"", 1))
         strcpy(member_string, substr(member_string, 2, strlen(member_string)-1));

      /* Remove any trailing period. */
      if (subcmp(member_string, ".", strlen(member_string)))
         strcpy(member_string, substr(member_string, 1, strlen(member_string)-1));

      if (subcmp(member_string, "'", strlen(member_string)) ||
          subcmp(member_string, "\"", strlen(member_string)))
         strcpy(member_string, substr(member_string, 1, strlen(member_string)-1));

      /* Check whether member_string already has an extension */
      found_period = FALSE;
      scandone = FALSE;
      *scanpos = 0;

      while (!scandone)
      {
         (*scanpos)++;
         scanchar = subchar(member_string, *scanpos);

         if (scanchar == '.')
            found_period = TRUE;

         scandone = (*scanpos >= (int) strlen(member_string) || found_period);
      }

      /* If not, then add .(ext) as the default extension */
      if (!found_period)
         strcat(member_string, extstr);

      strcpy(member, member_string);
      strcpy(cpfilerec, member_string);

      /* Write output to file */
      sprintf(line, "%s\n", cpfilerec);
      fwrite(line, sizeof(char), strlen(line), Outfile);
   }

   /* Scan past qualifier */
   do_mspq(infilerec, scanpos);
}


/***********************************************/
/** do_mste: PLI included code                **/
/***********************************************/
/* Comments: Scan to the end                   */
/***********************************************/
/* External variables: None                    */
/***********************************************/
void do_mste(char *infilerec, int *chars_found, int *scan_found, int *scanpos)
{
   char scanchar;

   *chars_found = FALSE;
   *scan_found = FALSE;

   while (*scanpos <= 72 && !(*scan_found))
   {
      scanchar = subchar(infilerec, *scanpos);

      switch(scanchar)
      {
      case '\'':
      case '\"':
            /* FHB function call */
            mss(infilerec, scanchar, scanpos);
            *chars_found = TRUE;
            break;

         case '=':
            if (*scanpos < 72 && subcmp(infilerec, "=", *scanpos+1))
            {
               *scanpos += 2;
               while (*scanpos <= 71 &&
                      !subcmp(infilerec, "=", *scanpos) &&
                      !subcmp(infilerec, "=", *scanpos+1))
                  (*scanpos)++;

               *scanpos += 2;
            }
            else
               (*scanpos)++;
            *chars_found = TRUE;
            break;

         case '.':
            if (*scanpos == 72 || subcmp(infilerec, " ", *scanpos+1))
               *scan_found = TRUE;
            else
            {
               (*scanpos)++;
               *chars_found = TRUE;
            }
            break;

         case ' ':
         case ',':
         case ';':
            (*scanpos)++;
            break;

         default:
            (*scanpos)++;
            *chars_found = TRUE;
            break;
      }
   }
}



/***********************************************/
/** do_mri: PLI included code                 **/
/***********************************************/
/* Comments: Main routine                      */
/***********************************************/
/* External variables: Infile                  */
/***********************************************/
void do_mri()
{
   char infilerec[80];

   while (!feof(Infile))
   {
      /* Read line */
      fgets(infilerec, sizeof(infilerec), Infile);

      /* Remove newline character */
      if (infilerec[0] && infilerec[strlen(infilerec)-1] == '\n')
         infilerec[strlen(infilerec)-1] = 0;

      /* Append spaces to make it 72 characters long */
      while (strlen(infilerec) < 72)
         strcat(infilerec, " ");

      if (!feof(Infile))
      {
         int copypos, inclpos;

         /* FHB function call */
         mclfc(infilerec, &copypos);

         if (copypos >= 8)
         {
            /* Local variables */
            int scanpos, scan_found, chars_found;
            char member[8];

            /* Porting problem??? */
            if (!subcmp(infilerec, " ", 8))
                  strncpy(&infilerec[7-INDEX_CONSTANT], substr(BLANKS80, 1, copypos-7), copypos-7);

            scanpos = copypos + 4;

            /* Find member name */
            do_mfmn(infilerec, member, &scanpos, EXT_CPY);

            /* Scan to the end */
            do_mste(infilerec, &chars_found, &scan_found, &scanpos);
         }
         else
         {
            /* FHB function call */
            mclfi(infilerec, &inclpos);

            if (inclpos >= 8)
            {
               /* Local variables */
               int scanpos, scan_found, chars_found;
               char member[8];

               /* Porting problem??? */
               if (!subcmp(infilerec, " ", 8))
                  strncpy(&infilerec[7-INDEX_CONSTANT], substr(BLANKS80, 1, inclpos-7), inclpos-7);

               scanpos = inclpos + 7;

               /* Find member name */
               do_mfmn(infilerec, member, &scanpos, EXT_SQB);

               /* Scan to the end */
               do_mste(infilerec, &chars_found, &scan_found, &scanpos);
            }
         }
      }
   }
}
