/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
 * rewrite_program.C - rewrite a program.
\*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/

#include  <stdlib.h>
#include  <stdio.h>
#include  <assert.h>
#include  <string.h>


/*--- Constants ---*/
#define  LINE_SIZE   1024

/*--- Start of Code ---*/


void   dump_code( FILE  * fl )
{
    fprintf( fl, 
           "#include  <assert.h>\n\n" 
           "bool  is_a_n__b_n__c_n()\n"
           "{\n"
           "    int  count_a = 0, count_b = 0, count_c = 0;\n"
           "    while  ( !feof( stdin ) ) { \n"
           "        int  ch;\n"
           "\n"
           "        ch = fgetc( stdin );\n"
           "        if  ( ch < 0 )\n"
           "            break;\n"
           "        if  ( ch == 'a' ) {\n"
           "            count_a++; \n"
           "            if  ( ( count_b > 0 )  ||  ( count_c > 0 ) )\n"
           "                return  false;\n"
           "        }\n"
           "        if  ( ch == 'b' ) {\n"
           "            count_b++; \n"
           "            if  (  count_c > 0 ) \n"
           "                return  false;\n"
           "        }\n"
           "        if  ( ch == 'c' ) \n"
           "            count_c++;         \n"
           "    }\n"
           "    return  ( count_a == count_b )  &&  ( count_b == count_c );\n"
           "}\n" );
    
    fprintf( fl, 
           "int  run_old_main( const char  * w )\n"
           "{\n"
           "    FILE  * fl = fopen( \"tmp\", \"wt\" );\n"
           "    assert( fl != NULL );\n"
           "    fputs( w, fl );\n"
           "    fclose( fl );       \n"
           "    stdin = fopen( \"tmp\", \"rt\" );    \n"
           "    assert( stdin != NULL );\n" 
           "    return  old_main();\n"
           "}\n" );
    fprintf( fl, 
           "\nint  new_main( const char  * w )\n"
           "{\n\n"
           "    if  ( is_a_n__b_n__c_n() ) \n"
           "        return  1;\n"
           "    if  ( run_old_main( w ) == 1 )\n"
           "        return  1;\n"
           "    else \n"
           "        return  0;\n"
             "}\n" );
}


void  copy_and_modify( FILE  * in, FILE  * out )
{
    char  line[ LINE_SIZE ];

    while  ( !feof( in ) ){ 
        char  * str = fgets( line, LINE_SIZE, in );
        if  ( str == NULL )
            break;
        if ( strcmp( line, "int  main()\n" ) == 0 ) 
            fprintf( out, "int  old_main()\n" );
        else
            fprintf( out, "%s", str );
    }
}


int  main( int  argc, char ** argv )
{
    FILE  * in, *out;

    //    fclose( stdin );
    if  ( argc != 4 ) {
        fprintf( stderr, "rewrite_program [input.C] inp_string [output.C]\n" );
        exit(-1);
    }

    in = fopen( argv[ 1 ], "rt" );
    out = fopen( argv[ 3 ], "wt" );
    assert( ( in != NULL )  &&  ( out != NULL ) );

    copy_and_modify( in, out );

    dump_code( out );

    fprintf( out,  "\n\n\n"
             "int   main()\n" 
             "{\n"
             "   int  ret = new_main( \"%s\" );\n"
             "   printf( \"returning  %cd\\n\", ret );\n"
             "   return  ret;\n" 
             "}\n", argv[ 2 ], '%' );
    fclose( in );
    fclose( out );

    return  0;
}

/* rewrite_program.C - End of File ------------------------------------------*/