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
Post a Comment