/****************************************************************************
*   Extract.c								    *
*   									    *
*   Chas A. Wyndham     15th May 1992. 					    *
*									    *	
*   Compiles under Lattice 5 and links with Decomp.o to make Hextract, a    *
*   programme for accessing header-file data.				    *
*									    *
*   This code is Freeware like Hextract itself.  You are welcome to improve *
*   it - but please send me a copy.					    *
*									    *
****************************************************************************/
  		
#include "exec/types.h"
#include "exec/memory.h"
#include "graphics/gfxbase.h"
#include "libraries/dos.h"
#include "intuition/intuition.h"
#include "intuition/intuitionbase.h"
#include "string.h"
#include "stdio.h"

struct IntuitionBase *IntuitionBase ;
struct GfxBase     *GfxBase ;
struct Screen      *screendata ; 
FILE               *fe ;
struct FileHandle  *window, *fi, *fo ;
char               buffer[100], line[256] ;
int                size, setcase = 0, found = 0, located = 0 ;
USHORT chip ptrImage[] = {  
	 0x0000, 0x0000,
	 0x6018, 0x0000,
	 0xc00c, 0x0000,
	 0xc30c, 0x0000,
	 0xc78c, 0x0000,
	 0xcccc, 0x0000,
	 0x7878, 0x0000,
	 0x3030, 0x0000,
	 0x0000, 0x0000,  };

struct FileLock *lock ;  
void   search(), showlib() ;
int    cleanup() ;
 
main(argc, argv)
int   argc ;
char  *argv[] ;
{
   char         ch = NULL, header[2], *ibuf, path[100] ;
   int          form, i = 0, result = 0, length ;
   
   
   IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 0) ;
   GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0) ;

   screendata = (struct Screen *)AllocMem(30, MEMF_PUBLIC) ;
   GetScreenData (screendata, 30, WBENCHSCREEN, NULL) ;
        
   stcgfp (path, argv[0]) ;
   strcat (path, "headers.z") ;
   
   form = GfxBase->NormalDisplayRows ;
   if (screendata->Height > 511)
    window = (struct FileHandle *)Open("CON:0/0/640/512/Hextract V1.1", MODE_NEWFILE) ;
   else if (screendata->Height >399)
    window = (struct FileHandle *)Open("CON:0/0/640/400/Hextract V1.1", MODE_NEWFILE) ;
   else if (screendata->Height >255)
    window = (struct FileHandle *)Open("CON:0/0/640/256/Hextract V1.1", MODE_NEWFILE) ;
   else 
    window = (struct FileHandle *)Open("CON:0/0/640/200/Hextract V1.1", MODE_NEWFILE) ;

   if ((fi = (struct FileHandle *)Open(path, MODE_OLDFILE)) == NULL) 
     { puts ("No headers.z file\n") ;
       cleanup()  ;
     }

   if ((fo = (struct FileHandle *)Open ("ram:headers.t", MODE_NEWFILE)) == NULL)
     { puts ("Can't create ram: file\n") ;
       Close(fi) ;
       cleanup() ;
     }
    
    Read(fi, header, 2) ;
	  
    if ((header[0] != 'L') || (header[1] != 'H'))
      {
        if((ibuf = (char *)AllocMem(4096, MEMF_PUBLIC)) == NULL)
          cleanup() ;
        do
         { length = Read (fi, ibuf, 4096) ;
           Write (fo, ibuf, length) ;
         } while (length) ;
        FreeMem (ibuf, 4096) ;
      }

    else result = decompress (fi, fo) ;

    Close (fi) ;
    Close (fo) ;
    if      (result == 1)  puts ("Decompression failed\n") ;
    else if (result == 2)  puts ("Out of memory\n") ;
    
   fe = fopen("ram:headers.t", "r+") ;
   Write (window, "                   Enter 'quit' to exit\n\n", 41) ;
   Write (window, "  Enter symbol\n\n   ", 18) ;
   onbreak(&cleanup) ;
      
   while (1)  
    { if (WaitForChar (window, 999999999)) 
      { Read (window, &ch, 1) ;
        buffer[i++] = ch ;
        if (!strcmp (buffer, "quit"))   break ;
        if (ch == '\n')
        { 
         buffer[--i] = '\0' ;
         if (i)
          { SetPointer (IntuitionBase->ActiveWindow, &ptrImage, 7, 16, -4, -4) ;
            search () ; 
            memset (buffer, '\0', 100) ;
            ClearPointer(IntuitionBase->ActiveWindow) ;
            Write (window, "\n  Enter symbol\n\n   ", 19) ;
          }
         i = 0 ;
        }
      }
    }
   cleanup() ;
}


int cleanup ()
{
     if (fe)     { fclose (fe) ;  fe = 0 ;  }
                   DeleteFile ("ram:headers.t") ; 
     if (lock)  UnLock(lock) ;
     if (window)  Close (window) ;
     if (GfxBase != NULL) CloseLibrary(GfxBase);
     if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
     exit(0);
}


fgts(buf)
char  *buf ;
{
   register char   c ;
   register int    i = 0 ;

   memset (buf, '\0', 256) ;
   c = getc (fe) ;
   while ((c != '\n') && (c != EOF))
    { buf[i++] = c ;
      c = getc (fe) ;
    }
   buf [i] = '\n' ;
   if (c == EOF)  return(0);
   else  return(1) ;
}


void search()
{  
   char   *tok, *tok2, temp[250], *match, *buf1, source[40], change = 0 ; 
   int    numbrackets = 0, libh = 0 ;

   size = 0 ;  located = 0 ;
   while (fgts (line) != 0)
    { buf1 = stpblk(line) ;
      if (!change)
        if (stcpma (buf1, "FFFFFF"))   change = 1 ; 
      if (change)
       { if (stcpm (buffer, ".resource", &match) || stcpm (buffer, ".device", &match)
                                         || stcpm (buffer, ".library", &match))
          { showlib() ;
            break ;
          }  
         if (stcpm (buf1, ".resource", &match) || stcpm (buf1, ".device", &match)
                                         || stcpm (buf1, ".library", &match))
          { tok = strtok (buf1, " \n") ;
            strcpy (source, tok) ;
            libh = 1 ;
            continue ;
       }  }
     
      strcpy (temp, buf1) ;
      tok = strtok (temp, " \n") ;
      if (astcsma(temp, buffer)) 
       { located = 1 ;        
         strcpy (temp, line) ;
         tok = strtok (line, " \n") ;
         tok2 = strtok (NULL, "\n") ;
         Write (window, "\n   ", 4) ; 
         Write (window, tok2, strlen(tok2)) ;
         if (libh)
          { Write (window, "  ", 2) ;
            Write (window, source, strlen(source)) ;
          }
         Write (window, "\n", 1) ;

         if (stcpm (temp, "struct", &match)) 
          { fgts (temp) ;
            if (strchr (temp, '{'))
             { numbrackets++ ;
               Write (window, "    ", 4) ; 
               Write (window, temp, strlen(temp)) ;
               while  (numbrackets) 
                { fgts(temp) ;

                  if (strchr (temp, '{'))
                   { numbrackets++ ;
                     Write (window, "    ", 4) ;
                     Write (window, temp, strlen(temp)) ;
                     continue ;
                   }
                  else if (strchr (temp, '}'))
                   { numbrackets-- ;
                     Write (window, temp, strlen(temp)) ;
                     continue ;
                   }

                  tok = strtok (temp, " \0") ;
                  tok2 = strtok (NULL, " \0") ;
                  Write (window, "    ", 4) ;
                  Write (window, tok2, strlen(tok2)) ;

                  do
                   { tok2 = strtok (NULL, " \0") ;
                     if (stcpm (tok2, "struct", &match))
                       { Write (window, "\n", 1) ;
                         break ;
                       } 
                     Write (window, " ", 1) ;
                     Write (window, tok2, strlen(tok2)) ;
                   } while (tok2) ; 
             }  }
          }

         tok = strtok (line, " \n") ;
         tok2 = strtok (NULL, "\n") ;
         Write (window, "\n       ", 8) ; 
         Write (window, tok2, strlen(tok2)) ;
    }  }
      
   if (!located)  Write (window, "        Not found\n", 18) ;
   rewind (fe) ; 
}


void showlib()
{
  char  *tok1, *tok2, buf[256] ;
  int num, i ;

  while (!stcpma (line, buffer))
    fgts (line) ;
  tok1 = strtok (line, " \n") ;
  tok2 = strtok (NULL, " \n") ;
  num = atoi (tok2) ;
  for (i = 0 ; i < num ; ++i)
   { fgts (buf) ;
     tok1 = strtok (buf, " \n") ;
     tok2 = strtok (NULL, "\0") ;
     Write (window, "   ", 3) ;
     Write (window, tok2, strlen(tok2)) ;
   }
  located = 1 ;
}
