VECPP Windows.c
#include "tape_t.h"
#include "string_t.h"
#include "tuple_t.h"
#include "bool_t.h"
#include <direct.h>
#if _MSC_VER
#include "io.h"
#else
#include <cunistd>
#endif
typedef bool_t _bool;
/**** 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_t 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;
SetGetIndex_hash_def_var(current_index,True);
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_t 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_def[64];
string_t args_caller[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_def[i] = copy(args[i]);
}
Deffunc[current_index].body = copy(func_body);
SetGetIndex_hash_def_func(current_index, True);
current_index++;
return current_index;
}
void parseHashFuncDef(string_t strline)
{
int offset = 0,args_counter=0, ln=length(strline);
string_t Define_func_name = tokenizeUsingOffset(strline, &offset);
string_t Define_bracket = tokenizeUsingOffset(strline, &offset);
string_t new_tok = tokenizeUsingOffset(strline, &offset);
string_t args[64];
while (compare_cstr(new_tok,")") != 0 && offset < ln)
{
if (compare_cstr(new_tok, ",") == 0)
;
else
{
args[args_counter] = copy(new_tok);
args_counter++;
}
string_destroy(new_tok);
new_tok = tokenizeUsingOffset(strline, &offset);
}
if (compare_cstr(new_tok, ")") != 0)
{
printf("error: expected ) !");
exit(0);
}
else
{ // fetch the function body
string_t line;
string_t func_body = string_const("");
while (line = getlines(strline))
{
if (at(line, line->len - 1) != '\\')
{
break;
}
else
{
concat(func_body, line);
}
}
insert_hash_defination_func_data(Define_func_name, args_counter, args, func_body);
string_destroy(func_body);
}
}
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)
{
HeaderTraversed[curr] = copy(header);
curr++;
}
_bool checkHeaderAlreadyIncluded(string_t header)
{
int i;
for (i = 0; i < curr; i++)
{
if (strncmp(HeaderTraversed[i]->str, header->str, header->len) == 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];
int SetGetIndex_ifdef_map(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_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[i] = 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, True);
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].line_no = lineno;
SetGetIndex_compilerdata(current_index, True); // setter for setting the index
current_index++;
return current_index;
}
string_t custom_hashinclude(string_t file)
{
int len = file->len;
static string_t slash = string_const("\\");
string_t cwd= string_const(""), full_path=string_const("");
if (at(file,len - 2) != 'h' || at(file,len - 3) != '.')
{
printf("error: %s: No such file or directory", file);
exit(0);
}
char* retCwd = 0;
#ifdef _MSC_VER
retCwd = _getcwd((char*)cwd->str, (size_t)cwd->len);
#else
retCwd = getcwd((char*)cwd->str, (size_t)cwd.length());
#endif
if (retCwd != NULL)
{
concat(full_path,cwd);
concat(full_path,slash);
concat(full_path,file);
// fetch_str_fromfile_singleline(full_path,content);
return full_path;
}
else
{
printf("getcwd() error\n");
}
return string_const("");
}
int search_file(const char* file_name)
{
// printf("Filename is %d\n", access(file_name,F_OK));
int ret = -1;
#if _MSC_VER
ret = _access(file_name, 0);
#else
ret = access(file_name, F_OK);
#endif
if (ret == 0)
{
return 1;
}
else
{
return -1;
}
return 0;
}
void system_hashinclude(string_t file, string_t path)
{
int i, k = 0, g, incl_dir_size = 3;
#if defined(_WIN32) || defined(_WIN64)
char slash[2] = "\\";
char incl_dir[3][128] = { "C:\\MinGW\\include",
"C:\\MinGW\\lib\\gcc\\mingw32\\6.3.0\\include",
"C:\\MinGW\\mingw32\\lib\\gcc\\mingw32\\6.3.0\\include",
};
#elif __linux
char slash[2] = "/";
char incl_dir[3][128] = { "/usr/local/include",
"/usr/target/include",
"/usr/include" };
#endif
char temp[128];
for (i = 0; i < incl_dir_size; i++)
{
memset(temp, 0, sizeof(temp));
#ifdef _MSC_VER
strcpy_s(temp, incl_dir[i]);
#else
strcpy(temp, incl_dir[i]);
#endif
k += sizeof(incl_dir[i]);
#ifdef _MSC_VER
strcat_s(temp, slash);
#else
strcat(temp, slash);
#endif
k += sizeof(slash);
#ifdef _MSC_VER
strcat_s(temp, file->str);
#else
strcat(temp, file->str);
#endif
k += sizeof(file->str);
//temp[k] = '\0';
if (search_file(temp) == 1) //search file at system level directory
{
printf("System directory found %s",temp);
string_t temp2 = string(temp);
path = overwrite(path, temp2);
// fetch_str_fromfile_singleline(file,content);
break;
}
}
}
/*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 parseHeaderFile(string_t withoutHashInc, bool_t* system_or_custom)
{
int end_pos = 0;
for (int i = 0; i < withoutHashInc->len; i++)
{
if ((withoutHashInc->str[i] == '>' && withoutHashInc->str[0] == '<') || (withoutHashInc->str[i] == '\"' && withoutHashInc->str[0] == '\"'))
break;
else
end_pos++;
}
char* c = withoutHashInc->str;
if (withoutHashInc->str[0] != '\"' && withoutHashInc->str[0] != '<')
{
printf("error: Not a header file, expected \" or > but got: %c\n", withoutHashInc->str[0]);
exit(0);
}
if (withoutHashInc->str[end_pos] != '\"' && withoutHashInc->str[end_pos] != '>')
{
printf("error: Not a header file, expected \" or > but got: %c\n", withoutHashInc->str[end_pos]);
exit(0);
}
else
{
if (withoutHashInc->str[0] == '\"')
{
*system_or_custom = False;
}
else if (withoutHashInc->str[0] == '<')
{
*system_or_custom = True;
}
}
withoutHashInc->str[0] = ' ';
withoutHashInc->str[end_pos] = ' ';
return end_pos;
}
void removeAtMiddle(string_t headercontent, string_t header, int include_loc, bool_t *system_or_custom)
{
shift_str(headercontent, include_loc, include_loc + header->len);
}
string_t fetchHeaderString(string_t HeaderFilecontent, int include_loc)
{
int length = 0;
int start_filename = 0;
int index = include_loc;
if (HeaderFilecontent->str[index] == '#')
{
index = index + 8;
while (HeaderFilecontent->str[index] == ' ' || HeaderFilecontent->str[index] == '\t' || HeaderFilecontent->str[index] == '\v')
index++;
start_filename = index;
for (int i = start_filename + 1; i < HeaderFilecontent->len; i++)
{
if ((HeaderFilecontent->str[i] == '>' && HeaderFilecontent->str[start_filename] == '<') || (HeaderFilecontent->str[i] == '\"' && HeaderFilecontent->str[start_filename] == '\"'))
{
index++;
break;
}
else
index++;
}
}
else
{
printf("error: fetchHeaderString unable to fetch header due to missing '#' \n");
exit(0);
}
length = index-include_loc+1;
return partOfstring(HeaderFilecontent, include_loc, length);
}
string_t fetchHeaderfile(string_t onlyHeaderFilecontent, int include_loc, bool_t *system_or_custom) // fetches stdio.h from #include <stdio.h>
{
string_t withoutHashInc = truncate(onlyHeaderFilecontent, include_loc + 8);
string_t HashIncwithoutSpace = removeExtraSpacesInFront(withoutHashInc);
int parse_len = parseHeaderFile(HashIncwithoutSpace, system_or_custom);
string_t HeaderFilenameWithSpaceInFront = truncateFromEnd(HashIncwithoutSpace, parse_len);
string_t HeaderFilename = removeExtraSpacesInFront(HeaderFilenameWithSpaceInFront);
string_destroy(withoutHashInc);
string_destroy(HashIncwithoutSpace);
string_destroy(HeaderFilenameWithSpaceInFront);
return HeaderFilename;
}
void getIncludeHeaderFullPath(string_t file, string_t path, bool_t system_or_custom_header_type)
{
if (system_or_custom_header_type == True)
{
system_hashinclude(file, path);
}
else if (system_or_custom_header_type == False)
{
custom_hashinclude(file);
}
// Tokens *curr_t;
// lex(file,curr_t); // should be parser
// file_lines=append_file(curr_t,prev_t);
}
/*void removeComments(string_t Filecontent)
{
static string_t StartComment = string_const("/*"); */
// static string_t EndComment = string_const("*/");
/* int start_loc = 0, end_loc = -1;
while((start_loc = findStringPos(Filecontent, StartComment,start_loc)) != -1 )
{
end_loc = findStringPos(Filecontent, EndComment, start_loc + 2);
printf("%s: %d, start_comment pos is:%d end_comment pos is: %d\n", __func__, __LINE__, start_loc, end_loc );
if(end_loc >= Filecontent->len)
{
printf("%s: %d error: terminated as end_loc crossed the file length(%d) !",__func__,__LINE__, end_loc);
break;
}
if (end_loc > start_loc && end_loc != -1)
{
shift_str(Filecontent, start_loc, end_loc + 2);
}
else
{
printf("%s: %d error: due to wrong end comment position(%d) !", __func__, __LINE__, end_loc);
break;
}
start_loc = end_loc + 2;
}
//printf("%s: %d, delete file content is: %s", __func__, __LINE__, Filecontent->str);
} */
void setCommentChars(string_t Filecontent,char replaceChar)
{
static string_t StartComment = string_const("/*");
static string_t EndComment = string_const("*/");
int start_loc = 0, end_loc = -1;
while ((start_loc = findStringPos(Filecontent, StartComment, start_loc)) != -1)
{
end_loc = findStringPos(Filecontent, EndComment, start_loc + 2);
if (end_loc >= Filecontent->len)
{
printf("\n%s: line no:%d error: terminated as end_loc crossed the file length(%d) !", __func__, __LINE__, end_loc);
break;
}
if (end_loc > start_loc && end_loc != -1)
{
printf("\n%s: line no:%d, start_comment pos is:%d end_comment pos is: %d\n", __func__, __LINE__, start_loc, end_loc);
for (int i = start_loc; i < end_loc + 2 && i < Filecontent->len; i++)
{
Filecontent->str[i] = replaceChar;
}
}
else
{
printf("\n%s: line no:%d error: due to wrong end comment position(%d) !", __func__, __LINE__, end_loc);
break;
}
start_loc = end_loc + 2;
}
//printf("%s: %d, delete file content is: %s", __func__, __LINE__, Filecontent->str);
}
void inliner(string_t onlyHeaderFilecontent) // call this one second
{
static string_t inc = string_const("#include");
bool_t system_or_custom_header_type = False;
int include_loc=0;
char* tape = {};
int file_length;
if ((include_loc = findStringPos(onlyHeaderFilecontent, inc, include_loc)) == -1 || onlyHeaderFilecontent->len < inc->len) // terminating condition
{
return;
}
string_t HeaderString = fetchHeaderString(onlyHeaderFilecontent, include_loc); // entire #include <abc.h>
string_t header = fetchHeaderfile(onlyHeaderFilecontent, include_loc, &system_or_custom_header_type);
string_t path = string_const("");
if (checkHeaderAlreadyIncluded(header)) // Ignore the header content and delete the entire #include
{
removeAtMiddle(onlyHeaderFilecontent, header, include_loc, &system_or_custom_header_type); // remove #include <abc..>
include_loc = include_loc + HeaderString->len;
}
else
{
markHeaderAlreadyIncluded(header);
getIncludeHeaderFullPath(header, path, system_or_custom_header_type);
tape = (char*)calloc(1, sizeof(char));
printf("\nHeader file name:%s header file len : %d, HeaderString:%s \n", header->str, header->len, HeaderString->str);
/* error handling if header file not present */
/*if (compare_cstr(path, "") == 0 && system_or_custom_header_type == true && header->len > 0)
{
include_loc = include_loc + HeaderString->len;
} */
if(system_or_custom_header_type == true)
tape_read(path->str, &tape);
else
tape_read(header->str, &tape); // header contains only stdio.h
string_t openFileContent = string_file(tape, &file_length);
setCommentChars(openFileContent, ' ');
//removeAtMiddle(onlyHeaderFilecontent, HeaderString, include_loc, &system_or_custom_header_type);
onlyHeaderFilecontent = concat(onlyHeaderFilecontent,openFileContent);
//printf("\n Headerfile content is: %s\n", onlyHeaderFilecontent->str);
removeAtMiddle(onlyHeaderFilecontent, HeaderString, include_loc, &system_or_custom_header_type); // remove #include <abc..>
printf("\n Headerfile content after header string removal is: %s\n", onlyHeaderFilecontent->str);
}
inliner(onlyHeaderFilecontent);
}
void StringReplacer() // 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 < SetGetIndex_hash_def_var(0,False); i++)
{
string_t symbol_to_be_replaced = Defvar[i].Def_str;
string_t replace_str = Defvar[i].Rep_str;
for (int j = 0; j < SetGetIndex_compilerdata(0,False); j++)
{
string_t strline = CompilerData[j].non_macro_dat;
while ((loc = locate(strline, symbol_to_be_replaced)) != -1)
{
delete_str(strline, loc, loc + symbol_to_be_replaced->len);
insert(strline, replace_str, loc);
}
}
}
for (int i = 0; i < SetGetIndex_hash_def_func(0, False); i++)
{
string_t symbol_to_be_replaced = Defvar[i].Def_str;
string_t replace_str_body = Defvar[i].Rep_str;
for (int j = 0; j < SetGetIndex_compilerdata(0, False); j++)
{
string_t strline = CompilerData[j].non_macro_dat;
while ((loc = locate(strline, symbol_to_be_replaced)) != -1)
{
delete_str(strline, loc, loc + symbol_to_be_replaced->len);
insert(strline, replace_str_body, loc);
}
}
}
}
void InsertOnlyTrueConditionBody(string_t newExpandedSrcCode) // call this one first
{
// Insert according to matching line number of non_macro_data and ifdef map struct, write the data to outputCLangFileContent
bool_t flag = False;
bool_t hasif_present = False;
int loc = 0,prev_loc = -1, tokenOffset=0;
while (loc = findCharNext(newExpandedSrcCode, '#', &loc) != -1)
{
tokenOffset = loc;
string_t new_tok = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
if (compare_cstr(new_tok, "#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_tok, "#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_tok, "#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_tok, "#endif") == 0)
{
if (hasif_present == False)
{
printf("#if is missing !\n");
exit(0);
}
hasif_present = (bool_t)False;
if (flag == False && prev_loc != -1)
{
delete_str(newExpandedSrcCode, prev_loc, loc - 1); // delete the body
}
flag = (bool_t)True;
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_tok = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
if (compare_cstr(new_tok, "#include") == 0)
{
string_t headerfile = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
delete_str(newExpandedSrcCode, loc, tokenOffset);
}
else if (compare_cstr(new_tok, "#define") == 0)
{
string_t Defstr = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
string_t Repstr = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
delete_str(newExpandedSrcCode, loc, tokenOffset);
}
else if (compare_cstr(new_tok, "#ifdef") == 0 || compare_cstr(new_tok, "#elif") == 0)
{
string_t conditionalvar = tokenizeUsingOffset(newExpandedSrcCode, &tokenOffset);
delete_str(newExpandedSrcCode, loc, tokenOffset);
}
else if (compare_cstr(new_tok, "#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, start = 0;
string_t s = string_const("");
while ((pos_hash = findCharNext(srcfilecontent, '#', &pos_hash)) != -1)
{
//string_t truc = truncate(mutableTempFileContent, pos_hash+1);
start = TokOffset;
string_t new_tok = tokenizeUsingOffset(srcfilecontent, &TokOffset);
if (compare_cstr(new_tok, "#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 = concat(s, fetchHeaderline);
}
pos_hash++;
}
inliner(s);
string_t ret = copy(s);
return ret;// return the expanded code without #include
}
bool_t is_id(string_t symbol)
{
if (symbol->len < 1)
{
printf("empty string\n");
return False;
}
int i = 0;
if (at(symbol, i) >= '0' && at(symbol, i) <= '9')
return False;
if ((at(symbol, i) >= 'a' && at(symbol, i) <= 'z') || (at(symbol, i) >= 'a' && at(symbol, i) <= 'z') || at(symbol, i) == '_')
{
if (symbol->len == 1)
{
return True;
}
i++;
while (i < symbol->len)
{
if ((at(symbol, i) >= '0' && at(symbol, i) <= '9') && (at(symbol, i) >= 'a' && at(symbol, i)) <= 'z' || (at(symbol, i) >= 'A' && at(symbol, i) <= 'Z') || at(symbol, i) == '_')
;
else
return False;
}
return True;
}
return False;
}
void lexer(string_t srcfilecontent)
{
int pos_hash = -1;
string_t mutableTempFileContent = copy(srcfilecontent);
int offset = 0,ln=0;
int start_func = 0;
while ((pos_hash = findCharNext(mutableTempFileContent, '#', &pos_hash)) != -1)
{
//string_t truc = truncate(mutableTempFileContent, pos_hash+1);
offset = pos_hash;
string_t new_tok = tokenizeUsingOffset(mutableTempFileContent, &offset);
if (compare_cstr(new_tok, "#define") == 0)
{
//string_t truc2 = truncate(trunc, pos_hash+8);
start_func = offset;
string_t Define_var_name = tokenizeUsingOffset(mutableTempFileContent, &offset);
ln = length(Define_var_name);
string_t Define_bracket_or_rep_name = tokenizeUsingOffset(mutableTempFileContent, &offset);
if (compare_cstr(Define_bracket_or_rep_name, "(") == True)
{
string_t funcmultiline = truncate(mutableTempFileContent, start_func);
parseHashFuncDef(funcmultiline);
}
else
{
insert_hash_defination_var(Define_var_name, Define_bracket_or_rep_name);
}
}
else if (compare_cstr(new_tok, "#ifdef") == 0)
{
string_t IfDef_check_name = tokenizeUsingOffset(mutableTempFileContent, &offset);
if (is_id(IfDef_check_name) == False)
{
printf("%s: line no: %d error: Ivalid symbol name : %s\n", __func__, __LINE__, IfDef_check_name->str);
exit(0);
}
}
else if (compare_cstr(new_tok, "#if") == 0)
{
string_t IfDef = tokenizeUsingOffset(mutableTempFileContent, &offset);
if (is_id(IfDef) == False)
{
printf("%s: line no: %d error: Ivalid symbol name : %s\n", __func__, __LINE__, IfDef->str);
exit(0);
}
}
else if (compare_cstr(new_tok, "#elif") == 0)
{
string_t ElIf = tokenizeUsingOffset(mutableTempFileContent, &offset);
if (is_id(ElIf) == False)
{
printf("%s: line no: %d error: Ivalid symbol name : %s\n", __func__, __LINE__, ElIf->str);
exit(0);
}
}
else if (compare_cstr(new_tok, "#endif") == 0)
{
}
else if (compare_cstr(new_tok, "##") == 0)
{
}
pos_hash++;
}
if (pos_hash == -1)
{
printf("completed !");
return;
}
}
void parser(string_t expandedsrcfilecontent)
{
// Order of calling the macro functions
InsertOnlyTrueConditionBody(expandedsrcfilecontent); // only the nonmacro content is required as input
StringReplacer(); // input the concatanated header and clang content
RemoveAllPreprocessorDirectives(expandedsrcfilecontent);
}
void Init_all_structs()
{
}
void start_cpp_driver(string_t src_file)
{
char* tape = {};
int t = 0;
tape = (char*)calloc(1, sizeof(char));
tape_read(src_file->str, &tape);
int file_length;
string_t OriginalFilecontent = string_file(tape, &file_length);
string_t ExpandedHeaderContent = split_hashinclude_data_from_clang(OriginalFilecontent);
lexer(ExpandedHeaderContent);
parser(ExpandedHeaderContent);
free(tape);
}
int main(int argc, char* argv[])
{
if (argc < 2)
{
printf("Error:No input file ! no of args is:%d", argc);
exit(0);
}
for (int i = 1; i < argc; i++)
{
string_t argfile = string(argv[i]);
int len = length(argfile);
if ((at(argfile, len - 2) == 'c' || at(argfile, len - 2) == 'h') && at(argfile, len - 3) == '.')
{
start_cpp_driver(argfile);
}
else
{
printf("Error:input file is invalid !");
exit(0);
}
}
}
Comments
Post a Comment