6bool FunctionBreakerC::is_define(
int line,
int pos){
7 int line_size = file_content.size();
9 if(pos+7 > line_size)
return false;
11 string token =
"#define";
13 for(
int j = 0; j < 7; j++){
14 match &= file_content[line][pos+j] == token[j];
21void FunctionBreakerC::filter_mask_commentaries_and_defines(vector<vector<bool>>& mask){
24 int number_lines = file_content.size();
25 bool is_open_block_comment =
false;
26 bool is_open_define =
false;
27 bool is_open_quotation_marks =
false;
28 bool is_open_line_comment =
false;
30 for(
int i = 0; i < number_lines; i++){
31 auto& line = file_content[i];
32 auto& mask_line = mask[i];
33 int line_size = line.size();
36 for(
int j = 0; j < line_size; j++){
40 if(line.back() !=
'\\'){
41 is_open_define =
false;
46 if(is_open_line_comment){
47 for(
int j = 0; j < line_size; j++){
51 if(line.back() !=
'\\'){
52 is_open_line_comment =
false;
57 for(
int j = 0; j < line_size; j++){
58 if(is_open_block_comment){
61 if(j+1 < line_size && line[j] ==
'*' && line[j+1] ==
'/'){
64 is_open_block_comment =
false;
69 if(is_open_quotation_marks){
73 is_open_quotation_marks =
false;
74 }
else if(line[j] ==
'\\'){
86 assert(j+1 < line_size &&
87 "source code does not compile, ' open but not closed");
91 assert(j+2 < line_size && line[j+2] ==
'\'' &&
92 "source code does not compile, ' open but not closed");
96 assert(j+1 < line_size && line[j+1] ==
'\'' &&
97 "source code does not compile, ' open but not closed");
101 mask_line[j] =
false;
106 is_open_quotation_marks =
true;
107 mask_line[j] =
false;
112 if(j == line_size-1){
116 if(line[j+1] ==
'/'){
117 for(
int k = j; k < line_size; k++){
118 mask_line[k] =
false;
122 is_open_line_comment = line.back() ==
'\\';
126 if(line[j+1] ==
'*'){
127 mask_line[j] =
false;
129 mask_line[j] =
false;
130 is_open_block_comment =
true;
136 for(
int k = j; k < line_size; k++){
137 mask_line[k] =
false;
141 is_open_define = line.back() ==
'\\';
147 assert(is_open_block_comment ==
false &&
148 "source code does not compile, open block comment");
149 assert(is_open_quotation_marks ==
false &&
150 "source code does not compile, open quotation marks");
154vector<vector<bool>> FunctionBreakerC::build_mask_valid_code(){
155 vector<vector<bool>> mask(file_content.size());
156 for(
int i = 0; i < (int)file_content.size(); i++){
157 mask[i] = vector<bool>(file_content[i].size(),
true);
159 filter_mask_commentaries_and_defines(mask);
163set<array<int,5>> FunctionBreakerC::find_start_end_and_depth_of_brackets(){
164 set<array<int,5>> start_ends;
165 int open_brackets = 0;
167 vector<pair<int,int>> not_processed_open_brackets;
168 auto process_open = [&](
int line_number,
int column){
170 not_processed_open_brackets.push_back({line_number,column});
172 auto process_close = [&](
int line_number,
int column){
174 if(open_brackets <= -1){
177 auto [matched_line,matched_column]= not_processed_open_brackets.back();
178 not_processed_open_brackets.pop_back();
179 int depth_of_open = not_processed_open_brackets.size();
180 start_ends.insert({matched_line,
188 for(
size_t i = 0; i < file_content.size(); i++){
189 auto& line = file_content[i];
190 for(
size_t j = 0; j < line.size(); j++){
191 if(!mask_valid[i][j]){
206set<array<int,4>> FunctionBreakerC::find_start_end_of_brackets_of_given_depth(){
207 set<array<int,4>>
ret;
208 set<array<int,5>> bracket_pairs = find_start_end_and_depth_of_brackets();
209 for(
auto [start_line,start_column,end_line,end_column,dep] : bracket_pairs){
210 if(dep == C_RELEVANT_DEPTH){
211 ret.insert({start_line,start_column,end_line,end_column});
217vector<string> FunctionBreakerC::build_function_content(
int start_number_line,
int start_column,
int end_number_line,
int end_column){
218 vector<string> function_content;
220 if(start_number_line == end_number_line){
222 for(
int j = start_column; j <= end_column; j++){
223 line += file_content[start_number_line][j];
225 function_content.push_back(line);
226 return function_content;
229 string first_line = file_content[start_number_line];
230 int first_line_size = first_line.size();
231 string first_line_contribution =
"";
232 for(
int j = start_column; j < first_line_size; j++){
233 first_line_contribution += first_line[j];
235 function_content.push_back(first_line_contribution);
237 for(
int i = start_number_line+1; i < end_number_line; i++){
238 function_content.push_back(file_content[i]);
241 string last_line = file_content[end_number_line];
242 int last_line_size = last_line.size();
243 string last_line_contribution =
"";
244 for(
int j = 0; j <= end_column; j++){
245 last_line_contribution += last_line[j];
247 function_content.push_back(last_line_contribution);
249 return function_content;
253bool FunctionBreakerC::move_pointer_until_character_outside_parenteses(
int &line,
int &column){
254 int quantity_open = 0;
255 bool has_parenteses =
false;
256 while(line != 0 || column != -1){
259 column = file_content[line].size();
264 auto c = file_content[line][column];
265 if(!mask_valid[line][column]){
271 has_parenteses =
true;
277 has_parenteses =
true;
287 assert( !(line == 0 && column == -1) &&
"code does not compile, bad formation of parenteses ()");
288 return has_parenteses;
292tuple<string,int,vector<string>> FunctionBreakerC::extract_header_related_information(
int start_line,
int start_column){
293 int line = start_line;
294 int column = start_column-1;
296 bool has_parenteses = move_pointer_until_character_outside_parenteses(line,column);
298 string file_name =
"";
300 auto c = file_content[line][column];
307 reverse(file_name.begin(),file_name.end());
309 move_pointer_until_character_outside_parenteses(line,column);
316 vector<string> header_content;
317 if(start_column == 0){
318 header_content = build_function_content(line,column,start_line-1,(
int)file_content[start_line-1].size() -1);
320 header_content = build_function_content(line,column,start_line,start_column-1);
323 if(!ALLOW_STRUCTS && !has_parenteses){
324 return {
"",-1,header_content};
326 return {file_name,line,header_content};
329bool FunctionBreakerC::is_body_function_empty(
int start_number_line,
int start_column,
int end_number_line,
int end_column){
330 vector<string> function_content = build_function_content(start_number_line, start_column, end_number_line, end_column);
331 int count_not_empty_char = 0;
332 for(
auto line : function_content){
335 count_not_empty_char++;
339 bool is_empty = count_not_empty_char <= 2;
343void FunctionBreakerC::process_function(
int start_number_line,
347 string relative_path){
348 string first_line = file_content[start_number_line];
349 auto [function_name, line_declaration, header_content] = extract_header_related_information(start_number_line,start_column);
350 if(function_name.empty()){
353 if(IGNORE_EMPTY_FUNCTIONS){
354 if(is_body_function_empty(start_number_line,start_column,end_number_line,end_column)){
358 vector<string> function_content = build_function_content(start_number_line,start_column,end_number_line,end_column);
360 create_source_file(start_number_line,end_number_line,relative_path,function_name,function_content);
362 create_info_file(line_declaration,start_number_line,end_number_line,relative_path,function_name);
365string FunctionBreakerC::file_path_from_folder_path(
string file_path,
string folder_path){
367 for(
size_t i = folder_path.size(); i < file_path.size(); i++){
373void FunctionBreakerC::file_breaker_c(
string file_path,
string folder_path){
374 string relative_path = file_path_from_folder_path(file_path, folder_path);
376 mask_valid = build_mask_valid_code();
378 set<array<int,4>> start_end_of_functions = find_start_end_of_brackets_of_given_depth();
379 for(
auto [start_line,start_column,end_line,end_column] : start_end_of_functions){
380 process_function(start_line,start_column,end_line,end_column,relative_path);
385 file_breaker_c(file_path, folder_path);
FunctionBreakerC(string file_path, string folder_path)
Constructs function breaker and processes file.
C/C++ function parsing and extraction.
void create_info_file(int line_declaration, int start_number_line, int end_number_line, string relative_path, string function_name)
Creates JSON metadata file for a function.
void create_header_file(string relative_path, string function_name, const vector< string > &header_content)
Creates header file for a function.
void create_source_file(int start_number_line, int end_number_line, string relative_path, string function_name, const vector< string > &function_content)
Creates source file for a function.
bool is_special_char(char c)
Checks if a character is special (non-alphanumeric and not underscore)
bool is_empty_char(char c)
Checks if a character is considered empty/whitespace.
vector< string > read_file_generic(string string_path)
Reads a file line by line into a vector of strings.