//***************************************************************************
// File name : startup.c
// Designer : Chih-Chieh Tsao
// Create date: Dec. 14, 2007
// Description:
//             Main program for static locating with dynamic loading,
//             modified from static loading part.
//
//**************************************************************************/

#include "locator.h"
#include "startup.h"

//#define DEBUG
#define DEBUG_A

/*******************************************************************
* Name: main function
* Argument:
*          command argument 1 : filename
********************************************************************/
int main(int argc, char *argv[])
{

    if(argc != 2)
    {
 	fprintf(stderr, "input error\n format: locator [filename]\n");
        return -1;
    }
    else
    {
        /* parser */
        fprintf(stderr, "\n\t[Parser] start ...\n\n");
        if (parser(argv[1]) != 0)
            exit(1);
        fprintf(stderr, "\n\t[Parser] end successfully!!!\n");
        fprintf(stderr, "\n--------------------------------------------\n");

        /* static loader */
        fprintf(stderr, "\n\t[Static Loader] start ...\n\n");
        if (loader() != 0)
            exit(2);
        fprintf(stderr, "\n\t[Static Loader] end successfully!!!\n");
        fprintf(stderr, "\n--------------------------------------------\n");

        /* static locator */
        fprintf(stderr, "\n\t[Locator] start ...\n\n");
        if (locator(argv[1]) != 0)
            exit(3);
        fprintf(stderr, "\n\t[Locator] end successfully!!!\n");
        fprintf(stderr, "\n--------------------------------------------\n");

        /* startup code */
        fprintf(stderr, "\n\t[Startup Code Attached] start ...\n\n");
        if (startup(argv[1]) != 0)
            exit(4);
        fprintf(stderr, "\n\t[Startup Code Attached] end successfully!!!\n");
        fprintf(stderr, "\n--------------------------------------------\n");
        
        /* generate data binary file */
        generate_data_binary(strtok(argv[1], "."));

#ifdef DEBUG_A
    fprintf(stderr, "text_size = %d bytes !\n", text_size);
    fprintf(stderr, "bss_size = %d bytes !\n", bss_size);
    fprintf(stderr, "data_size = %d bytes !\n", data_size);
#endif

    }

    return 0;
}


/*******************************************************************
* Name: generate_data_binary
* Input: char *file_name
* Output: int
* Description: 
*           generate binary file for data segment 
*
********************************************************************/
int generate_data_binary(char *file_name)
{
    FILE *outFP;
    char *output_file_name = strcat(file_name, "_data.out");  //output filename(.bin)
    gVars *tmp = all_data;
    char *data;             //data would be written to the file
    int res=0;

    // open write binary file and error check
    outFP = fopen(output_file_name, "wb");
    if(outFP == NULL)
    {
 	fprintf(stderr, "Open output binary file error !!!\n");
	return -1;
    }      


    /***************************************
     * write related addresses (link script) into binary file
     * contain three infomations in order :
     *   text segment size 
     *   bss  segment size
     *   data segment size
     ***************************************/    
    fwrite(&text_size, sizeof(char), 4, outFP);
    fwrite(&data_size,  sizeof(char), 4, outFP);
    fwrite(&bss_size, sizeof(char), 4, outFP);
    fwrite(&res, sizeof(char), 4, outFP);           //fill zero to binary (reserved for future)
     

    //while loop for writing the data segment into binary file
    while(tmp != NULL)
    {        
        while ( ( data = (char *)(*tmp->variables) ) != NULL )
        {
#ifdef DEBUG
            fprintf(stderr, "===\ndata =  %s \n", data);
            fprintf(stderr, "data+2 =  %s \n", data+2);
            fprintf(stderr, "idata = %d\n", strlen(data+2));
            fprintf(stderr, "int = %d", HexToDec(data+2, strlen(data+2)));
#endif
        
            res = HexToDec(data+2, strlen(data+2));
            fwrite(&res, sizeof(char), 4, outFP);

            tmp->variables ++;
        }
        
        tmp = (gVars *)tmp->link;
        if (tmp == NULL)
            break;

    }

    fprintf(stderr, "\n  Output Binary file (data segment) : %s\n", output_file_name);
    fprintf(stderr, "\n--------------------------------------------\n");
    fclose(outFP);

    return 0;
}


