#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#include <dos/dos.h>
#include <dos/rdargs.h>
#include <clib/dos_protos.h>
#include <pragmas/dos.h>

#define TEMPLATE "FILES/A/M,FDPREFIX/K,FDSUFFIX/K,RESOURCE/S,DEFSONLY/S,USEDEFS/S"
#define OPT_FILES           0
#define OPT_FDPREFIX        1
#define OPT_FDSUFFIX        2
#define OPT_RESOURCE        3
#define OPT_DEFSONLY        4
#define OPT_USEDEFS         5
#define OPT_COUNT           6

LONG opts[OPT_COUNT];

char *ver="\0$VER: buildwatch Snoopy Support Tool 1.2 (01.01.94)";
char *fdPrefix = "FD:";
char *fdSuffix = "_lib.fd";
extern struct Library *DOSBase;

int ParseFDFile( char *basename )
{
    FILE *fp;
    char buffer[256];
    long bias;
    char *Basis = "UNKNOWN";
    char fPrivate;
    char fname[80];

    sprintf( fname, "%s%s%s", fdPrefix, basename, fdSuffix);

    if( ( fp = fopen( fname, "rt" ) ) == NULL )
    {
        printf("ERROR: cannot open %s\n", fname );
        return 10;
    }

    bias = 0; fPrivate = FALSE;

    printf("; Snoopy scriptfile for \"%s\"\n\n", fname );

    while( !feof( fp ) )
    {
        fgets( buffer, 256, fp );

        if( *buffer == '*' ) continue;

        if( *buffer == '#' && *(buffer+1) == '#' )
        {
            if( strnicmp( buffer+2, "bias", 4) == 0 )
            {
                bias = atol( buffer + 7 ); 
            }
            else if( strnicmp( buffer+2, "public", 6 ) == 0 )
            {
                fPrivate = FALSE;
            }
            else if( strnicmp( buffer+2, "private", 7 ) == 0 )
            {
                fPrivate = TRUE;
            }
            else if( strnicmp( buffer+2, "base", 4 ) == 0 )
            {
                char *cp;
                Basis = strdup( buffer+8 );
                cp = strchr( Basis, '\n' );
                if( cp ) *cp=0;
                if( !opts[OPT_DEFSONLY] )
                {
                    if( opts[OPT_RESOURCE] )
                    {
                        printf("resource=%s,%s.resource\n",Basis,basename );
                    }
                    else
                    {
                        printf("base=%s,%s.library\n",Basis,basename );
                    }
                    if( opts[OPT_USEDEFS] )
                    {
                        printf("include=%s\n",basename);
                    }                        
                }
            }
        }
        else
        {
            if( !fPrivate )
            {
                char *cp;
                char Regs[80];
                char *name;

                if( ( cp = strchr( buffer, '(' ) ) != NULL )
                {
                    *cp = 0;
                    name = strdup( buffer );
                }
                else continue;

                if( ( cp = strrchr( ++cp, (int)'(' ) ) != NULL )
                {
                    int done = FALSE;
                    int count = 0;
                    int nrofregs = 0;
                    
                    do
                    {
                        switch( *cp )
                        {
                        case ',':
                            *cp = '/';
                        case '/':
                            Regs[ count++ ] = 'L';
                            nrofregs++;
                        case 'A':
                        case 'a':
                        case 'D':
                        case 'd':
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                            Regs[ count++ ] = toupper( *cp );
                            break;
                        case ')':
                            done = TRUE;
                            break;
                        }
                        cp++;
                    }
                    while( !done );
                    if( count != 0 )
                    {
                        nrofregs++;
                        Regs[ count++ ] = 'L';
                        Regs[ count++ ] = '/';
                    }
                    Regs[ count ] = 0;
                        
                    strcat( Regs, "RD0L" );
                    if( opts[OPT_DEFSONLY] )
                    {
                        printf("define=%s,-%ld\n",name,bias);
                    }
                    else
                    {
                        if( opts[OPT_USEDEFS] )
                        {
                            printf("watch=%s,%s,%s,%s( ", Basis, name, Regs, name );
                        }                        
                        else
                        {
                            printf("watch=%s,-%ld,%s,%s( ", Basis, bias, Regs, name );
                        }
                        for( ; nrofregs; nrofregs--) printf("$%%lx ");
                        printf(")=$%%lx\n");
                    }
                }
            }
            bias += 6;
        }
    }
    fclose( fp );
    return 0;
}

int main(int argc, char *argv[])
{
    struct RDArgs *argsptr;

    if( ( argsptr = ReadArgs( TEMPLATE, opts, NULL ) ) != NULL )
    {
        char **sptr;

        if( opts[OPT_DEFSONLY] && (opts[OPT_USEDEFS]|opts[OPT_RESOURCE]) )
        {
            printf( "Sorry, DEFSONLY/S cannot appear along with USEDEFS/S or RESOURCE/S\n");
        }
        else
        {
            if( opts[OPT_FDPREFIX] ) fdPrefix = (char *)(opts[OPT_FDPREFIX]);
            if( opts[OPT_FDSUFFIX] ) fdSuffix = (char *)(opts[OPT_FDSUFFIX]);
            sptr = (char **)(opts[OPT_FILES]);
            while( *sptr ) ParseFDFile( *(sptr++) );
        }
        FreeArgs( argsptr );
    }
    else
    {
        PrintFault( IoErr(), NULL );
        return RETURN_ERROR;
    }
    return RETURN_OK;
}
