#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#define POINT_NUM1 inputNum1+outputNum1+wireNum1
#define POINT_NUM2 inputNum2+outputNum2+wireNum2


int inputNum1,outputNum1,wireNum1;
int inputNum2,outputNum2,wireNum2;
FILE *out;

typedef struct tPoint{
	char type;
	char *name;
	int value;
	int level;
	struct tPoint *incone;
	struct tPoint *gateInput;
	struct tPoint *gateOutput;
}Point;
Point *pointG1,*pointG2;

typedef struct tHashTable{
	char valid;
	char *data;
	struct tHashTable *next;
}HashTable;
int HashTable_CollisoinMax;
HashTable *h1,*h2;

int strGetHashKey(char *str , int gSeq);


void initialize();
void readCircuit(char **);
void buildGraph();
void resourceRelease();

int main(int argc , char **argv){
	initialize();
	out = fopen (argv[3],"w");
	 
	readCircuit(argv);
	
	printf("i,o,w=%d,%d,%d\n",inputNum1,outputNum1,wireNum1);
	printf("i,o,w=%d,%d,%d\n",inputNum2,outputNum2,wireNum2);
	buildGraph();
	resourceRelease();	
	
//	fclose(out);
}
void initialize(){	
	inputNum1=0;  outputNum1=0;  wireNum1=0; 
	inputNum2=0;  outputNum2=0;  wireNum2=0; 	
	HashTable_CollisoinMax=0;
}
void readCircuit(char **argv){
	
	
    char str[10000],key[10],strcat[5000000],*token;
    int w_now,in_now,gate_o,edgeType;
    int i,j,k;
    FILE *in1,*in2;
    
    in1 = fopen (argv[1],"r");
    in2 = fopen (argv[2],"r"); 
    out = fopen (argv[3],"w");
    if(in1==NULL || in2==NULL)
    {
        perror("Error opening file");
    }
    else{
    /*------------------1pass of input1----------------------------------*/
        while(!feof(in1)){

           fgets(str,10000,in1);
           i=0; j=0; k=0;           
//fprintf(out,"nowline:%s , length=%d\n",str,strlen(str));               
           while(str[i]==' ' || str[i]=='\t' || str[i]=='\n') i++;  //Note 過濾tab用\t 
           while((str[i]!=' ') && (str[i]!='\n') ){
                key[k]=str[i];
                i++; k++;  
           } 
           key[k]='\0';
//fprintf(out,"+--key=%s\n",key);         
           if(strcmp(key,"module")==0){
                if(str[strlen(str)-2]!=';'){
                    do{
//                        fprintf(out,"     filter:%s %d %d\n",str,str[strlen(str)-1],'\n');
                        fgets(str,10000,in1);            //換行字元不會中斷此函式 
                    }while(str[strlen(str)-2]!=';');               
                }
           }
		   else if(key[0]=='/' && key[1]=='/') {  fprintf(out,"comment\n"); ;continue;}
		   else if(key[0]=='\0') {   fprintf(out,"blank line\n");continue;}
           else if(strcmp(key,"endmodule")==0) break;
           else{               
                if(str[strlen(str)-2]!=';'){
				
                    do{
//fprintf(out,"muti? %c\n",str[strlen(str)-2]); 
                     while(str[i]==' ') i++;
                     while(str[i]!='\n'){ 
                            strcat[j]=str[i]; 
                            i++; j++; 
                     } 
//fprintf(out,"     filter:%s",str);
                        fgets(str,10000,in1);            //換行字元不會中斷此函式 
                        i=0; 
                    }while(str[strlen(str)-2]!=';'); 
                     while(str[i]==' ') i++;
                     while(str[i]!='\n'){ 
                            strcat[j]=str[i]; 
                            i++; j++; 
                     }  
                     strcat[j]='\0';                                    
                }
                else{ // single line 
                    while(str[i]==' ') i++;
                    while(str[i]!=';'){
                         strcat[j]= str[i];
                         i++; j++; 
                    }
                    strcat[j]='\0';                     
               }                    
//fprintf(out,"Multi-Line Merged/single str:\n%s\n",strcat);
            
               if(strcmp(key,"input")==0){
                    token = strtok(strcat," ,\t;");
                    while(token!=NULL){
                        token = strtok(NULL," ,\t;");
                        inputNum1++;
                    }

               }
               else if(strcmp(key,"output")==0){
                    token = strtok(strcat," ,\t;");
                    while(token!=NULL){
                        token = strtok(NULL," ,\t;");
                        outputNum1++;
                    }                    
               }
               else if(strcmp(key,"wire")==0){
                    token = strtok(strcat," ,\t;");
                    while(token!=NULL){
//fprintf(out,"token=%s\n",token);
                        token = strtok(NULL," ,\t;");
                        wireNum1++;
                    }                    
               }
               else{
				   
//				  printf("this key word \"%s\" is invalid\n",key);
			   }      
           }                     
           
        }//end read line 
fprintf(out,"-------First pass of in1 Done--------------\n");		
 /*------------------1pass of input2----------------------------------*/
        while(!feof(in2)){

           fgets(str,10000,in2);
           i=0; j=0; k=0;           
//fprintf(out,"nowline:%s , length=%d\n",str,strlen(str));               
           while(str[i]==' ' || str[i]=='\t' || str[i]=='\n') i++;  //Note 過濾tab用\t 
           while((str[i]!=' ') && (str[i]!='\n') ){
                key[k]=str[i];
                i++; k++;  
           } 
           key[k]='\0';
//fprintf(out,"+--key=%s\n",key);         
           if(strcmp(key,"module")==0){
                if(str[strlen(str)-2]!=';'){
                    do{
//                        fprintf(out,"     filter:%s %d %d\n",str,str[strlen(str)-1],'\n');
                        fgets(str,10000,in2);            //換行字元不會中斷此函式 
                    }while(str[strlen(str)-2]!=';');               
                }
           }
		   else if(key[0]=='/' && key[1]=='/') {  fprintf(out,"comment\n"); ;continue;}
		   else if(key[0]=='\0') {   fprintf(out,"blank line\n");continue;}
           else if(strcmp(key,"endmodule")==0) break;
           else{               
                if(str[strlen(str)-2]!=';'){
				
                    do{
//fprintf(out,"muti? %c\n",str[strlen(str)-2]); 
                     while(str[i]==' ') i++;
                     while(str[i]!='\n'){ 
                            strcat[j]=str[i]; 
                            i++; j++; 
                     } 
//fprintf(out,"     filter:%s",str);
                        fgets(str,10000,in2);            //換行字元不會中斷此函式 
                        i=0; 
                    }while(str[strlen(str)-2]!=';'); 
                     while(str[i]==' ') i++;
                     while(str[i]!='\n'){ 
                            strcat[j]=str[i]; 
                            i++; j++; 
                     }  
                     strcat[j]='\0';                                    
                }
                else{ // single line 
                    while(str[i]==' ') i++;
                    while(str[i]!=';'){
                         strcat[j]= str[i];
                         i++; j++; 
                    }
                    strcat[j]='\0';                     
               }                    
//fprintf(out,"Multi-Line Merged/single str:\n%s\n",strcat);
            
               if(strcmp(key,"input")==0){
                    token = strtok(strcat," ,\t;");
                    while(token!=NULL){
                        token = strtok(NULL," ,\t;");
                        inputNum2++;
                    }

               }
               else if(strcmp(key,"output")==0){
                    token = strtok(strcat," ,\t;");
                    while(token!=NULL){
                        token = strtok(NULL," ,\t;");
                        outputNum2++;
                    }                    
               }
               else if(strcmp(key,"wire")==0){
                    token = strtok(strcat," ,\t;");
                    while(token!=NULL){
//fprintf(out,"token=%s\n",token);
                        token = strtok(NULL," ,\t;");
                        wireNum2++;
                    }                    
               }
               else{
				   
//				  printf("this key word \"%s\" is invalid\n",key);
			   }      
           }                     
           
        }//end read line 
fprintf(out,"-------First pass of in2 Done--------------\n");		
	
	}//valid FILE ptr
	fclose(in1);
	fclose(in2);
	fclose(out);
}

void buildGraph(){
	int i;
	pointG1 = (Point *)malloc((POINT_NUM1+2)*sizeof(Point));
	for(i=0;i<POINT_NUM1+2;i++){
		(pointG1+i)->type ='e';
		(pointG1+i)->value=0;
		(pointG1+i)->level=-1;
		(pointG1+i)->incone=NULL;
		(pointG1+i)->gateInput=NULL;
		(pointG1+i)->gateOutput=NULL;		
	}
	printf("part1,pNUm1=%d\n",POINT_NUM1);
	h1 = (HashTable *)malloc(POINT_NUM1*sizeof(HashTable));
	printf("part2\n");
	for(i=0;i<POINT_NUM1;i++){
		printf("part3,i=%d,%d\n",i,POINT_NUM1);
		(h1+i)->valid ='i';
		(h1+i)->data=NULL;
		(h1+i)->next=NULL;
	}
	printf("part4\n");
}
void resourceRelease(){
	
	free(pointG1); free(pointG2);
	free(h1); free(h2);
}

int strGetHashKey(char *str , int gSeq){
	int i,x=0;
	for(i=0;i<strlen(str);i++) x=x+str[i];
	x = (gSeq==1)? x%POINT_NUM1 : POINT_NUM2;
	return x;
}