VECPP.c

#include <tape_t.h>
#include <string_t.h>
#include <tuple_t.h>
#include <bool_t.h>

/**** first design #include, #define VAR, #define FUNC() and #ifdef, #elif and #endif *****/
enum MacroType {
    define_t,
    include_t,
    line_t,
    undef_t,
    error_tt,
    pragma_t,
    defined_t,
    if_t,
    ifdef_t,
    ifndef_t,
    elif_t,
    else_t,
    endif_t,
    COMPILER_DATA,
    UNDEFINED,
    MAX_TYPE
};
MacroType getIndexFromStr(string_t s)
{
    string_t tmp;
    char* arr[13] = { "define","include","line","undef","error","pragma","defined","if","ifdef","ifndef","elif","else","endif" };
    for(int i=0; i< 13; i++)
    {
        tmp = string(arr[i]);
        if((compare(tmp,s)) == 0)
            return (MacroType) i;
    }
    return UNDEFINED;
}

struct Define_var_map
{
   int lineno;
   int end_scope_lineno;
   string_t Def_str;
   string_t Rep_str;
} Defvar[2048];

int SetGetIndex_hash_def_var(int index, _bool SetOrGet)
{
static int max_index;
if(SetOrGet == TRUE)
{
max_index = index;
return max_index;
}
else if(SetOrGet == FALSE)
{
return max_index;
}
return -1;
}
int insert_hash_defination_var(int lineno, string_t Def, string_t Rep)
{
static int current_index;
if(current_index >= 2048)
{
   printf("erro: no space left in #define var table!");
       return -1;    
}
Defvar[current_index].lineno = lineno;
Defvar[current_index].Def_str = Def;
Defvar[current_index].Rep_str = Rep;
current_index++;
return current_index;
}

int search_hash_defination_var(string_t Def)
{
for(int i=0; i< SetGetIndex_hash_def_var(0,FALSE); i++)
{
if(compare(Defvar[i].Def_str,Def) == 0)
{
            return i;
}
}
return -1;
}
_bool update_hash_defination_end_scope(string_t Def,int end_scope_lineno)   /* #undef */
{
for(int i=0; i< 2048; i++)
{
if(compare(Defvar[i].Def_str,Def) == 0)
{
Defvar[i].end_scope_lineno = end_scope_lineno;
            return TRUE;
}
}
return FALSE;
}

struct Define_fun_map
{
   int lineno;
   int end_scope_lineno;
   string_t Def_fun_str;
   int args_len;
   string_t args[64];
   string_t body;
} Deffunc[1024];

int SetGetIndex_hash_def_func(int index, _bool SetOrGet)
{
static int max_index;
if(SetOrGet == TRUE)
{
max_index = index;
return max_index;
}
else if(SetOrGet == FALSE)
{
return max_index;
}
return -1;
}

int insert_hash_defination_func_data(int lineno, string_t DefFun,int args_len, string_t *args, string_t func_body)
{
static int current_index;
Deffunc[current_index].lineno = lineno;
Deffunc[current_index].Def_fun_str = DefFun;
Deffunc[current_index].args_len = args_len;
for(int i=0; i<args_len; i++)
{
Deffunc[current_index].args[i] = copy(args[i]);
}
    Deffunc[current_index].body = copy(func_body);
SetGetIndex_hash_def_func(current_index,TRUE);
current_index++;
return current_index;
}
struct Include_map
{
    string_t filename;
    int line_number;
  //  string_t filecontent;
}IncMap[1024];

int SetGetIndex_include_content(int index, _bool SetOrGet)
{
static int max_index;
if(SetOrGet == TRUE)
{
max_index = index;
return max_index;
}
else if(SetOrGet == FALSE)
{
return max_index;
}
return -1;
}

void insert_hash_include_content(string_t filename, int line_number)
{
static int current_index;
IncMap[current_index].filename = filename;
IncMap[current_index].line_number = line_number;
SetGetIndex_include_content(current_index, TRUE);
current_index++;
}

string_t HeaderTraversed[500];
static int curr=0;
void markHeaderAlreadyIncluded(string_t header)
{
    copy(HeaderTraversed[curr],header);
    curr++;
}

_bool checkHeaderAlreadyIncluded(string_t header)
{
   for(i=0; i<= curr; i++)
   {
      if(compare(HeaderTraversed[i],header) == 0)
      {
         return TRUE;
      }

   }
   return FALSE;

}

struct If_def_map
{
  int if_line_no;
  int endif_line_no;
  _bool ifndef;  // tells whether it's if/ifdef ot ifndef
  int no_of_elif;
  int elif_linenos[64];
  string_t hash_elifs_var[64];
  string_t entireIfendIfBlock; // lexer will store the entire #if... #endif block inside tape

}IfBlockAnalyzer[1024];

void insert_ifdef_map(int if_line_no, int endif_line_no,_bool ifndef, int no_of_elif, int *elif_linenos,string_t *hash_elifs, string_t entireIfendIfBlock)
{
static int current_index;
IfBlockAnalyzer[current_index].if_line_no = if_line_no;
IfBlockAnalyzer[current_index].endif_line_no = endif_line_no;
IfBlockAnalyzer[current_index].ifndef = ifndef;
IfBlockAnalyzer[current_index].no_of_elif = no_of_elif;
for(int i=0; i< no_of_elif; i++)
{ IfBlockAnalyzer[current_index].elif_linenos[i] = elif_linenos[i];
  IfBlockAnalyzer[current_index].hash_elifs_var = copy( hash_elifs[i]);
    }
    IfBlockAnalyzer[current_index].entireIfendIfBlock = copy(entireIfendIfBlock);
current_index++;
}


struct Lex_Macro_data
{
   int line_no;
   MacroType type;
   string_t macro_str_data;
   int def_var_map_index;
   int def_func_map_index;
   int def_include_map_index;
   int if_map_index;
}MacroLexAnalyzer[2048];

int SetGetIndex_macrolexdata(int index, _bool SetOrGet)
{
static int max_index;
if(SetOrGet == TRUE)
{
max_index = index;
return max_index;
}
else if(SetOrGet == FALSE)
{
return max_index;
}
return -1;
}

int insert_macro_data(int line, MacroType ty, string_t str,int macro_index)
{
static int current_index;
if(current_index >= 2048)
    {
       printf("error: cannot open anymore !");
   return -1;
}
MacroLexAnalyzer[current_index].line_no = line;
MacroLexAnalyzer[current_index].type = ty;
MacroLexAnalyzer[current_index].macro_str_data = str;
MacroLexAnalyzer[current_index].def_var_map_index = -1;
MacroLexAnalyzer[current_index].def_func_map_index = -1;
MacroLexAnalyzer[current_index].def_include_map_index = -1;
MacroLexAnalyzer[current_index].if_map_index = -1;
switch(ty)
{
case define_t:
  MacroLexAnalyzer[current_index].def_var_map_index = macro_index;
break;
case include_t:
  MacroLexAnalyzer[current_index].def_include_map_index = macro_index;
break;
case if_t:
  MacroLexAnalyzer[current_index].if_map_index = macro_index;
break;
        case ifdef_t:
  MacroLexAnalyzer[current_index].if_map_index = macro_index;
break;
        
case ifndef_t:
  MacroLexAnalyzer[current_index].if_map_index = macro_index;
break;
}
SetGetIndex_macrolexdata(current_index);
current_index++;
return current_index;
}

struct Lex_Non_macro_data
{
   int line_no;
   string_t non_macro_dat;
}CompilerData[5096];

int SetGetIndex_compilerdata(int index, _bool SetOrGet)
{
static int max_index;
if(SetOrGet == TRUE)
{
max_index = index;
return max_index;
}
else if(SetOrGet == FALSE)
{
return max_index;
}
return -1;
}

int insert_non_macro_data(int lineno, string_t normal_clang_str)
{
static int current_index;
CompilerData[current_index].non_macro_dat = normal_clang_str;
CompilerData[current_index].lineno = lineno;
SetGetIndex_compilerdata(current_index,TRUE); // setter for setting the index
current_index++;
return current_index;
}



bool_t is_sys_header_str(string_t headerfile)
{
   if(at(headerfile, 0) == '<'  && at(headerfile, headerfile->len -1) == '>')
     return TRUE;
   else 
     return FALSE;
}
bool_t is_custom_header_str(string_t headerfile)
{
   if(at(headerfile, 0) == '\"'  && at(headerfile, headerfile->len -1) == '\"')
     return TRUE;
   else 
     return FALSE;
}
int fetchHeaderFile(string_t withoutHashInc)
{
     int end_pos = 0;
     char *c = withoutHashInc->str;
     if(withoutHashInc->str[end_pos] != '\"' &&  withoutHashInc->str[end_pos] != '>')
     {
        printf("error: Not a header file");
        exit(0);
     }
     withoutHashInc->str[end_pos] = ' ';
     while(withoutHashInc->str[end_pos] != '\n' && withoutHashInc->str[end_pos] != EOF)
     {
         end_pos++;
     }
     if(withoutHashInc->str[end_pos-1] != '\"' && withoutHashInc->str[end_pos-1] != '>')
     {
        printf("error: Not a header file");
        exit(0);       
     }
     
     return end_pos;
    
}


string_t inc =  string("#include");
void inliner(string_t onlyHeaderFilecontent) // call this one second
{
   int include_loc;
    if((include_loc=locate(onlyHeaderFilecontent, inc)) == -1 || onlyHeaderFilecontent->len < inc->len) // terminating condition
    {
       return; 
    }
    
    string_t withoutHashInc = truncate(onlyHeaderFilecontent, include_loc+8);
    string_t HashIncwithoutSpace = removeExtraSpacesInFront(withoutHashInc);
    string_t header = truncateFromEnd(HashIncwithoutSpace, fetchHeaderFile(HashIncwithoutSpace));
    if(checkHeaderAlreadyIncluded(header)) // Ignore the header content and delete the entire #include
    {
       removeAtMiddle(onlyHeaderFilecontent, header, include_loc); // remove #include <abc..>
    }
    else
    {    
      markHeaderAlreadyIncluded(header);
      string_t openFileContent = string_file(header);
      removeAtMiddle(onlyHeaderFilecontent, header, include_loc); // remove #include <abc..>
      onlyHeaderFilecontent = con(onlyHeaderFilecontent, openFileContent);
      
    }
    inliner(onlyHeaderFilecontent);
}

void StringReplacer(struct Define_var_map *var, int *len_var, struct Define_func_map *fn, int *len_func ,struct Lex_non_macro_data * ExpandedSrcFile,int* ExpandedsrcFile_len) // call this one at last
{
  // #undef , before the line of #undef the string replacer will replace but after the line of #undef , stringreplacer won't work for the undef variable
   int loc = 0;
   for(int i=0; i< *len_var; i++)
   {
      string_t symbol_to_be_replaced = *var[i]->Def_str;
      string_t replace_str =  *var[i]->Rep_str;
      for(int j=0; j< *ExpandedsrcFile_len ; j++)
      {
          string_t strline = ExpandedSrcFile[j]->non_macro_dat; 
          if((loc=locate(strline, symbol_to_be_replaced)) != -1)
          {
               delete_str(strline,loc,loc+symbol_to_be_replaced->len);
               insert(strline,replace_str,loc); 
          
          }
         
      }
   
   }

}
void InsertOnlyTrueConditionBody(string_t outputCLangFileContent) // call this one first
{
  // Insert according to matching line number of non_macro_data and ifdef map struct, write the data to outputCLangFileContent
    _bool flag = FALSE;
_bool hasif_present = FALSE;
int prev_loc = -1;
    while(loc=findCharNext(newExpandedSrcCode,'#', loc) != -1)
{
tokenOffset = loc;
          string_t new = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);       
          if(compare_cstr(new, "#if") == 0)
  {
  if(hasif_present == TRUE)
  {
  printf("#if is already present !\n");
  exit(0);
  }
  hasif_present = TRUE;
  // search in the map the variable
  string_t Defstr = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
  if(search_hash_defination_var(Defstr) != -1)
  {
    flag = TRUE;
  }
  else // do deletion of body, store the start loc, as the #if VAR, VAR doesn't exist
  {
  prev_loc = tokenOffset;
  flag = FALSE;
   
  }
  
  }
  else if(compare_cstr(new, "#ifdef") == 0)
  {
  if(hasif_present == TRUE)
  {
  printf("#if is already present !\n");
  exit(0);
  }
  hasif_present = TRUE;
  string_t Defstr = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
  if(search_hash_defination_var(Defstr) != -1)
  {
    flag = TRUE;
  }
  else // do deletion of body, store the start loc, as the #if VAR, VAR doesn't exist
  {
  prev_loc = tokenOffset;
  flag = FALSE;
   
  }
  
  }
  else if(compare_cstr(new, "#elif") == 0)
  {
  if(hasif_present == FALSE)
  {
  printf("#if is missing !\n");
  exit(0);
  }
  if(flag == FALSE && prev_loc != -1)
      {
  delete_str(newExpandedSrcCode,prev_loc, loc-1); // delete the body
  
  }
  
  string_t Defstr = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
  if(search_hash_defination_var(Defstr) != -1)
  {
    flag = TRUE;
  }
  else // do deletion of body, store the start loc, as the #if VAR, VAR doesn't exist
  {
  prev_loc = tokenOffset;
  flag = FALSE;
   
  }
  }
  else if(compare_cstr(new, "#endif") == 0)
  {
  if(hasif_present == FALSE)
  {
  printf("#if is missing !\n");
  exit(0);
  }
  hasif_present = FALSE;
  if(flag == FALSE && prev_loc != -1)
      {
  delete_str(newExpandedSrcCode,prev_loc, loc-1); // delete the body
  
  }
  flag = FALSE;
  prev_loc = -1;
  }
  
}

}
void RemoveAllPreprocessorDirectives(string_t newExpandedSrcCode)
{
     int loc = 0;
     int tokenOffset = 0;
     while(loc=findCharNext(newExpandedSrcCode,'#', loc) != -1)
     {
          tokenOffset = loc;
          string_t new = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);       
          if(compare_cstr(new, "#include") == 0)
      {
            string_t headerfile = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
            delete_str(newExpandedSrcCode,loc,tokenOffset); 

      }  
      else if(compare_cstr(new, "#define") == 0)
      {
            string_t Defstr = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
            string_t Repstr = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
            delete_str(newExpandedSrcCode,loc,tokenOffset); 

      }
      else if(compare_cstr(new, "#ifdef") == 0 || compare_cstr(new, "#elif") == 0)
      {
             string_t conditionalvar = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
             delete_str(newExpandedSrcCode,loc,tokenOffset); 

      }
      else if(compare_cstr(new, "#endif") == 0)
      {
            delete_str(newExpandedSrcCode,loc,tokenOffset);
      }
}


}
string_t split_hashinclude_data_from_clang(string_t srcfilecontent) // #include only need to seperate from clang and return the expanded file
{
     int pos_hash = 0;
     int TokOffset = 0;
     string_t s=string("");
     while((pos_hash = findCharNext(srcfilecontent , '#', pos_hash)) != -1)
    {
       //string_t truc = truncate(mutableTempFileContent, pos_hash+1);
       start = TokOffset;
       string_t new = tokenizeUsingOffset(srcfilecontent, &TokOffset);
       if(compare_cstr(new, "#include") == 0)
       {
         // string_t truc2 = truncate(trunc, pos_hash+8);
          string_t tok = tokenizeUsingOffset(srcfilecontent, &TokOffset);
          string_t fetchHeaderline = partOfstring(srcfilecontent,pos_hash, TokOffset - start);
          s=append(s,fetchHeaderline);
       
       }
       pos_hash++;
    }
     
    inliner(s);
    string_t ret = copy(s);
    return ret;// return the expanded code without #include
}

string_t tokenizeUsingOffset(string_t str, int *offset)
{
        //string_t str_withoutSpaces;
        int i=*offset;
        while(str->str[i] == ' ' || str->str[i] != '\t' || str->str[i] != '\v' || str->str[i] == '\n')
          i++;
        int len = 0;
        while(str->str[i] != ' ' && str->str[i] != '\t' && str->str[i] != '\v' )
        {
          i++;
          len++;
        }        
        char *s = (char *) malloc(sizeof(char) * len);
        for(int k=0, j=*offset; k<len; k++,j++)
        {
            s[k] = str->str[j];
        }
        *offset = i;
        return string(s);
}

void lexer(string_t srcfilecontent)
{
    int pos_hash= -1;
    string_t mutableTempFileContent = srcfilecontent;
    int TokOffset = 0;
    while((pos_hash = findCharNext(mutableTempFileContent , '#', pos_hash)) != -1)
    {
       //string_t truc = truncate(mutableTempFileContent, pos_hash+1);
       string_t new = tokenizeUsingOffset(mutableTempFileContent, &TokOffset);
       else if(compare_cstr(new, "#define") == 0)
       {
          //string_t truc2 = truncate(trunc, pos_hash+8);
          string_t Define_var_name = tokenizeUsingOffset(truc2_withoutSpaces, &offset);
          ln = length(Define_var_name);
          string_t Define_rep_name = tokenizeUsingOffset(truc2_withoutSpaces, &offset);       
       
       }
       else if(compare_cstr(new, "#ifdef") == 0)
       {
          string_t IfDef_check_name = tokenizeUsingOffset(truc2_withoutSpaces, &offset);
           
       
       
       }
       else if(compare_cstr(new, "#if") == 0)
       {
          string_t IfDef =  tokenizeUsingOffset(truc2_withoutSpaces, &offset);
       
       
       }
       else if(compare_cstr(new, "#elif") == 0)
       {
           string_t ElIf =  tokenizeUsingOffset(truc2_withoutSpaces, &offset);
       
       }
       else if(compare_cstr(new, "#endif") == 0)
       {
       
       
       }
       else if(compare_cstr(new, "##") == 0)
       {
          
       
       }
     
       pos_hash++;

    }
    if(pos_hash == -1)
    {
       printf("completed !");
       return;
    }
   
}
void parser()
{

   // Order of calling the macro functions
   // InsertTrueConditionBody(), only the nonmacro content is required as input
   // Concatanate Header and Clang content
   // StringReplacer() , input the concatanated header and clang content
   // RemoveAllPreprocessorDirectives()
}

void Init_all_structs()
{


}

void start_cpp_driver(string_t src_file)
{
  char *tape = {};
  int t = 0, i;
  tape = (char*)calloc(1, sizeof(char));
  tape_read(src_file, &tape);
  int file_length;
  string_t OriginalFilecontent = string_file(tape,&file_length);
  string_t ExpandedHeaderContent = split_hashinclude_data_from_clang(OriginalFilecontent);
  lexer();
  parser();
  free(tape);
}
int main(int argc,char *argv[])
{
    if(argc < 2)
    {
       printf("Error:No input file !");
       exit(0);
    }

    for(int i=1; i< argc; i++)
    {
        string_t argfile = string(argv[i]);
        int len = length(argfile);
        if((at(argfile , len-1) == 'c' || at(argfile , len-1)=='h') && at(argfile , len-2) == '.')
        {
            start_cpp_driver(argfile);            
        }
        else
        {
           printf("Error:input file is invalid !");
           exit(0);
        }
    }


}
 

Comments

Popular posts from this blog

Comparision with Quick Sort

Interview questions