extern void found( int , char *);
#define TCHAR char
#define LEN 256

#include <stdio.h>
#include <ctype.h>
#include <malloc.h>
#include <string.h>
#include <assert.h>
#include "myopt.h"
#define TRUE 1
#define FALSE 0

#define MAX_NUMBER 100
#define MAX_PARMS    8

#define max(a,b) (((a) > (b)) ? (a) : (b))

struct _apitype {
    char *pchName;
    char *pchformat;
    int   cb;
    int   cParms;
    int   iOrder[MAX_PARMS];
} apilist[MAX_NUMBER];
int api_num = -1;


FILE *fp_src, *fp_dst, *fp_err, *fp_dat;
char chFirstBuf[53];
int token_length = 0;
int bVerbose = FALSE;
int  bBinary  = FALSE;

#define m_iswspace(a) (isspace(a) && (a) != '\n')

char *get_token( char *pch)
{
    char *pch2;

    while (*pch)
        {
        if (isalnum(*pch))
            {
            if (strchr( chFirstBuf, *pch))
                {
                pch2 = pch;
                while(isalnum(*pch2)) pch2++;
                token_length = (int)(pch2 - pch);
                return(pch);
                }
            do
                {
                pch++;
                } while(isalnum(*pch));
            }
        while (*pch && !isalnum(*pch))
            {
            pch++;
            } 
        }
    return(NULL);
}

char ch1[50] = "WinSendMsg";
char ch2[50] = "S %s\n";
char ch3[50] = "WinPostMsg";
char ch4[50] = "P %s\n";
char ch5[50] = "WinSendDlgItemMsg";
char ch6[50] = "D %s\n";

void init_dat(int bDump)
{
    int ii, jj;

    api_num = 3;

    strcpy(chFirstBuf, "W");

    for (ii = 0; ii < api_num; ii++)
        for (jj = 0; jj < MAX_PARMS; jj++)
            apilist[ii].iOrder[jj] = -1;

    apilist[0].pchName = ch1;
    apilist[0].cb      = 10;
    apilist[0].cParms  =  4;
    apilist[0].pchformat = ch2;
    apilist[0].iOrder[0] = 1;

    apilist[1].pchName = ch3;
    apilist[1].cb      = 10;
    apilist[1].cParms  =  4;
    apilist[1].pchformat = ch4;
    apilist[1].iOrder[0] = 1;

    apilist[2].pchName = ch5;
    apilist[2].cb      = 17;
    apilist[2].cParms  =  5;
    apilist[2].pchformat = ch6;
    apilist[2].iOrder[0] = 2;

}



void add_buff(char *pch)
{
    char chExtraLine[256];
    fgets( chExtraLine, 256, fp_src);
    if (bVerbose)
        fputs( chExtraLine, fp_err);

    strcat( pch, chExtraLine);
}

void found( int index, char *pch)
{
    char chApiBuf[2048];
    char chRestBuf[256];
    char *pchIn = pch;
    char *pchOut = chApiBuf;
    char *pchEnd;
    char pchParms[MAX_PARMS][256];
    char *parmlist[MAX_PARMS];
    struct _apitype *api = &apilist[index];
    int nest = 0;
    int iParmNo = 0;
    int string = 0;
    int ii;
    char ch;

    for (ii = 0; ii < MAX_PARMS; ii++)
        {
        pchParms[ii][0] = 0x00;
        parmlist[ii]    = NULL;
        }

    strncpy( chApiBuf, pch, api->cb);
    pchIn += api->cb;
    pchOut = chApiBuf + api->cb;
    while (iswspace(*pchIn)) pchIn++;
    assert( *pchIn == '(');
   *pchOut++ = *pchIn++;
    nest = 1;

    while (nest > 0)
        {
        ch = *pchOut++ = *pchIn++;
        if (ch == '(') nest++;
        if (ch == ')') nest--;
        if (ch == '\'' || ch == '\"')
            {
            char chEnd = ch;

            do
                {
                ch = *pchOut++ = *pchIn++;
                if (ch == '\\')
                    ch = *pchOut++ = *pchIn++;
                if (ch == 0x00)
                    {
                    pchIn--;
                    pchOut--;
                    add_buff(pchIn);
                    }
                }
            while (ch != chEnd);
            }
        if (ch == 0x00)
            {
            pchIn--;
            pchOut--;
            add_buff(pchIn);
            }
        }

    *pchOut = 0x00;
    strcpy( chRestBuf, pchIn);
    pchIn = chApiBuf + api->cb + 1;
//    printf( "Api (%s) Rest (%s)\n", chApiBuf, chRestBuf);
    if (api->pchformat == NULL)
        {
        strcpy( pch, chRestBuf);
        return;
        }

    nest = 1;
    iParmNo = 0;
    pchEnd = pchIn;

    while (nest > 0)
        {
        int  cb;
        char *pchBeginLoop = pchEnd;

        ch = *pchEnd;
        while (isspace(ch) || isalnum(ch)
            || strchr("&*.[]-></+|?!%=^_:", ch) ) ch = *++pchEnd;

        if ( ! (strchr("\"\'(),", ch)))
            printf("Invalid character %c\n", ch);

        assert( ch != 0x00);

        if (ch == '\"' || ch == '\'')
            {
            char chEnd = ch;
            do
                {
                ch = *++pchEnd;
                if (ch == '\\')
                    ch = *++pchEnd;
                }
            while (ch != chEnd);
            ch = *++pchEnd;
            }
        if (ch == '(') 
            {
            nest++;
            ++pchEnd;
            }
        if (ch == ')') 
            {
            nest--;
            if (nest == 0)
                {
                cb = pchEnd - pchIn;
                strncpy(pchParms[iParmNo], pchIn, cb);
                pchParms[iParmNo++][cb] = 0x00;
                pchIn += cb + 1;
                pchEnd = pchIn;
                }
            else
                ++pchEnd;
            }
        if (ch == ',' )
            {
            if (nest == 1)
                {
                cb = pchEnd - pchIn;
                strncpy(pchParms[iParmNo], pchIn, cb);
                pchParms[iParmNo++][cb] = 0x00;
                pchIn += cb + 1;
                pchEnd = pchIn;
                }
            else
                ++pchEnd;
            }
        if(pchBeginLoop == pchEnd)
            pchEnd++;
        }

    for (ii = 0; ii < MAX_PARMS; ii++)
        {
        if (api->iOrder[ii] != -1)
            parmlist[ii] = pchParms[api->iOrder[ii]];
        else
            parmlist[ii] = NULL;
        }

    sprintf( pch, api->pchformat, parmlist[0], parmlist[1],
        parmlist[2], parmlist[3], parmlist[4], parmlist[5],
        parmlist[6], parmlist[7]);

    fputs( pch, fp_dst);
    strcat(pch, chRestBuf);

}

char *FindApi( char *pch)
{
    int ii;
    char *ptr;

    for (ii = 0; ii < api_num; ii++)
        {
        if ( token_length == apilist[ii].cb &&
                *pch == apilist[ii].pchName[0] &&
                (strncmp( pch, apilist[ii].pchName, apilist[ii].cb) == 0))
            {
            ptr = pch + apilist[ii].cb;
            while (iswspace(*ptr)) ptr++;
            if (*ptr == '(')
                {
                found(ii, pch);
                return( pch + 1);
                }
            }
        }

    return( pch + 1);
}

void useage()
{
    printf( "Useage: msgstat file \n");
}

main( argc, argv)
	int argc;
	char *argv[];
    {
    int ii;
    char src[30];
    char dst[30];
    char buffer[2560];
    char *ptr;
    int  bDump = FALSE;
    char chDataFile[34] = "define.dat";
    char chBinFile[34] = "ms_ssed.bin";
    char *pchDataFile = chDataFile;
    char *pchBinFile = chBinFile;

    int  bCompile = FALSE;

    ii = 1;

    src[0] = 0x00;
    dst[0] = 0x00;

    while (ii = my_getopt(argc, argv, ""))
        {
        switch (ii)
            {
            case -1:
                if (src[0] == 0x00)
                    {
                    strcpy(src, p_optstr);
                    break;
                    }

                // FALL THRU

            default:
                useage();
                return(0);
            }
        }
    
    if (src[0] == 0x00 )
        {
        useage();
        return(0);
        }

    fp_src = stdin;
	fp_dst = stdout;
	fp_err = stderr;

    fp_src = freopen( src, "rt", stdin);

    if (fp_src == NULL)
        {
        printf( "Could not open %s\n", src);
        return(0);
        }

    init_dat(FALSE);

    while (fgets( buffer, 256, fp_src))
        {
        ptr = buffer;
        while (ptr = get_token( ptr))
            {
            ptr = FindApi(ptr);
            }
        }
    fclose(fp_src);
    fclose(fp_dst);
    }

