1
1
#include < bits/stdc++.h>
2
2
#include < regex>
3
+ #define t_section tuple<string, string, bool >
3
4
using namespace std ;
4
5
6
+ const bool USE_HASH = true ;
7
+ const int HASH_LEN = 3 ;
5
8
6
9
const vector<string> IGNORED_LINES = {
7
10
" #include <bits/stdc++.h>" ,
@@ -38,9 +41,7 @@ const string BLOCK_DESC_END = "BLOCK_DESC_END";
38
41
39
42
const bool USE_MARKDOWN_IN_DESC = true ;
40
43
41
- // hash incompleto - não usar
42
- const bool USE_HASH = false ;
43
- const int HASH_LEN = 3 ;
44
+ const bool IGNORE_EMPTY_LINES = false ;
44
45
45
46
map<char32_t , char > char_changes = {
46
47
{0x00E7 , ' c' }/* ç*/ , {0x00E3 , ' a' }/* ã*/ , {0x00E1 , ' a' }/* á*/ ,
@@ -56,22 +57,29 @@ map<char32_t, char> char_changes = {
56
57
{U' \x20 19' , ' \' ' }, {U' \x3b 1' , ' a' }, {U' \x20 13' , ' -' },
57
58
};
58
59
59
- // // Code Start Here ////
60
+ // // Code Start Here ///
61
+ #include " hash/md5hsh.cpp" // Include another hash function if you want to use other
62
+ const string HASH_CODE = " ./hash/md5hsh.cpp" ; // Path to the hash code that will be used (To put on lib)
63
+ string _get_code_hash_ (string code){
64
+ return getCodeHash (code, HASH_LEN);
65
+ }
66
+
60
67
const string COMMENT_BLOCK_DESC_BGN = R"( /\*+\s*)" + BLOCK_DESC_BGN;
61
68
const string COMMENT_BLOCK_DESC_END = BLOCK_DESC_END + R"( \s*\*+/)" ;
62
69
63
70
void remove_whitespace (string& s){
64
- while (!s.empty () && (s.back () == ' \n ' || s. back () == ' \t ' || s. back () == ' \r ' || s. back () == ' ' ))
71
+ while (!s.empty () && isspace (s.back ()))
65
72
s.pop_back ();
66
73
}
67
74
68
75
void remove_front_whitespace (string& s){
69
76
int skp = 0 ;
70
- while (skp < s.size () && (s. front () == ' \n ' || s. front () == ' \t ' || s. front () == ' \r ' || s. front () == ' ' ))
77
+ while (skp < s.size () && isspace (s[skp] ))
71
78
skp++;
72
79
s.erase (0 , skp);
73
80
}
74
81
82
+
75
83
void remove_ignored_substrings (string& s) {
76
84
size_t pos = 0 ;
77
85
for (const auto & substr : IGNORED_SUBSTRINGS)
@@ -153,14 +161,16 @@ bool is_comment(string line) {
153
161
if (line.size () >= 2 and line.substr (0 , 2 ) == " /*" ) comment = true ;
154
162
return comment;
155
163
}
156
-
164
+
165
+ const string BLOCK_DESC_MARK = " BLOCK_DESC_MARK\n " ;
157
166
bool convert_files (const string& input_path, const string& output_path, string& description, bool PRINT_HASH = false ){
158
167
ifstream in (input_path, ios::binary);
159
168
if (!in){ cerr << " Error opening input file: " << input_path << endl; return false ; }
160
169
string content ((istreambuf_iterator<char >(in)), istreambuf_iterator<char >());
161
170
in.close ();
162
171
163
172
bool can_begin = false , isInDesc = false , ignore_interval = false , isInBlckDesc = false ;
173
+ vector<string> block_descs, block_desc_desc;
164
174
string processed_content, line, block_desc=" " ;
165
175
description = " " ;
166
176
size_t pos = 0 ;
@@ -219,8 +229,14 @@ bool convert_files(const string& input_path, const string& output_path, string&
219
229
remove_front_whitespace (block_desc);
220
230
remove_whitespace (processed_content);
221
231
block_desc = block_desc.empty () ? " \n " : " \n @\\ blockdesc{" + block_desc + " }@\n " ;
222
- if (BLOCK_DESC) processed_content += block_desc;
223
- else description += block_desc + " \n " ;
232
+ if (isInDesc){
233
+ block_desc_desc.emplace_back (block_desc),
234
+ description += BLOCK_DESC_MARK;
235
+ }
236
+ else {
237
+ block_descs.emplace_back (block_desc);
238
+ processed_content += " \n " + BLOCK_DESC_MARK;
239
+ }
224
240
can_begin = false ;
225
241
isInBlckDesc = false ;
226
242
block_desc.clear ();
@@ -238,6 +254,7 @@ bool convert_files(const string& input_path, const string& output_path, string&
238
254
239
255
if (ADD_DESC && isInDesc && !ignore){ description += line + " \n " ; continue ; }
240
256
if (line.find (DESC_END) != string::npos) isInDesc = false ; // if(line.find(MY_DESC_END) != string::npos) isInDesc = false;
257
+ if (IGNORE_EMPTY_LINES && blank_line) continue ;
241
258
242
259
if (!ignore && !blank_line) can_begin = true ;
243
260
if (!can_begin || ignore) continue ;
@@ -254,7 +271,21 @@ bool convert_files(const string& input_path, const string& output_path, string&
254
271
remove_ignored_substrings (description);
255
272
description = convert_description (description);
256
273
257
- // if(PRINT_HASH) processed_content = get_file_hash(processed_content);
274
+ if (PRINT_HASH) processed_content = _get_code_hash_ (processed_content);
275
+
276
+ for (auto blck : block_descs){
277
+ auto bgn = processed_content.find (BLOCK_DESC_MARK);
278
+ int sz = BLOCK_DESC_MARK.size ();
279
+ while (bgn > 0 && processed_content[bgn] != ' \n ' ) bgn--, sz++;
280
+ processed_content.replace (bgn, sz, blck);
281
+ }
282
+
283
+ for (auto blck : block_desc_desc){
284
+ auto bgn = description.find (BLOCK_DESC_MARK);
285
+ int sz = BLOCK_DESC_MARK.size ();
286
+ while (bgn > 0 && description[bgn] != ' \n ' ) bgn--, sz++;
287
+ description.replace (bgn, sz, blck);
288
+ }
258
289
259
290
// Ensure output directory exists
260
291
filesystem::path out_path (output_path);
@@ -281,19 +312,19 @@ string get_style(const string& filename) {
281
312
return " txt" ;
282
313
}
283
314
284
- string get_tex (const vector<pair<string, vector<pair<string, string >>>> & sections, bool PRINT_HASH= false ) {
315
+ string get_tex (const vector<pair<string, vector<t_section >>>& sections) {
285
316
string tex, description;
286
317
for (auto & [section_name, subsections] : sections) if (!subsections.empty ()){
287
318
tex += " \\ section{" + section_name + " }\n " ;
288
319
289
- for (auto [filename, subsection_name] : subsections){
320
+ for (auto [filename, subsection_name, file_hash ] : subsections){
290
321
cout << get_style (filename) + " \t | " << filename << endl;
291
322
if (get_style (filename) == " tex" ){ tex += " \\ input{" + filename + " }\n " ; continue ; }
292
323
293
324
string newpath = " ./temp/" + filename, full_path = filename;;
294
- newpath = regex_replace (newpath, regex (R"( \.\./)" ), " " ); // remove qualquer ../ de newpath
325
+ newpath = regex_replace (newpath, regex (R"( \.\./|\./ )" ), " " ); // remove qualquer ../ ou ./ de newpath
295
326
296
- if (convert_files (full_path, newpath, description, PRINT_HASH))
327
+ if (convert_files (full_path, newpath, description, USE_HASH&&file_hash&& get_style (filename)== " cpp " ))
297
328
full_path = newpath;
298
329
299
330
tex += " \\ vspace{-2pt}\n " ;
@@ -315,8 +346,8 @@ string get_tex(const vector<pair<string, vector<pair<string, string>>>>& section
315
346
return tex;
316
347
}
317
348
318
- vector<pair<string, vector<pair<string, string> >>> get_sections () {
319
- vector<pair<string, vector<pair<string, string> >>> sections;
349
+ vector<pair<string, vector<t_section >>> get_sections () {
350
+ vector<pair<string, vector<t_section >>> sections;
320
351
321
352
ifstream f (" contents.txt" , ios::binary); // For UTF-16 handling on Windows
322
353
@@ -339,7 +370,7 @@ vector<pair<string, vector<pair<string, string>>>> get_sections() {
339
370
if (line.empty ()) continue ;
340
371
if (line.find (' #' ) < line.size ()) continue ;
341
372
342
- if (line[0 ] == ' [' ) sections.emplace_back (line.substr (1 , line.size () - 2 ), vector<pair<string, string> >());
373
+ if (line[0 ] == ' [' ) sections.emplace_back (line.substr (1 , line.size () - 2 ), vector<t_section >());
343
374
else {
344
375
size_t div_pos = line.find (div_char);
345
376
if (div_pos >= line.size ()) {
@@ -348,18 +379,21 @@ vector<pair<string, vector<pair<string, string>>>> get_sections() {
348
379
continue ;
349
380
}
350
381
382
+ bool file_hash = true ;
383
+ if (line.find (' @' ) < line.size ()) file_hash = false , line[line.find (' @' )] = ' ' ;
384
+
351
385
string filename = line.substr (0 , div_pos);
352
- while (!filename.empty () && (filename.back () == ' ' || filename. back () == ' \t ' )) filename.pop_back ();
386
+ while (!filename.empty () && isspace (filename.back ())) filename.pop_back ();
353
387
string subsection_name = line.substr (div_pos + 1 );
354
- while (! subsection_name. empty () && (subsection_name. back () == ' ' || subsection_name. back () == ' \t ' )) subsection_name. pop_back ( );
355
- while (! subsection_name. empty () && (subsection_name. front () == ' ' || subsection_name. front () == ' \t ' )) subsection_name. erase ( 0 , 1 );
388
+ remove_whitespace ( subsection_name);
389
+ remove_front_whitespace ( subsection_name);
356
390
357
391
if (sections.empty ()) {
358
392
cerr << " Subsection given without section {" << line << " } " << line.size () << endl;
359
393
continue ;
360
394
}
361
395
362
- sections.back ().second .emplace_back ( filename, subsection_name);
396
+ sections.back ().second .push_back ( t_section ({ filename, subsection_name, file_hash}) );
363
397
}
364
398
}
365
399
@@ -369,7 +403,19 @@ vector<pair<string, vector<pair<string, string>>>> get_sections() {
369
403
370
404
int main (){
371
405
auto sections = get_sections ();
372
- string tex = get_tex (sections, USE_HASH);
406
+
407
+ if (USE_HASH)
408
+ {
409
+ bool added_hash = false ;
410
+ for (auto & [section_name, subsections] : sections)
411
+ if (section_name == " Extra" )
412
+ subsections.push_back (t_section ({HASH_CODE, " Hash Function" , true })),
413
+ added_hash = true ;
414
+ if (!added_hash)
415
+ sections.emplace_back (" Extra" , vector<t_section>({t_section ({HASH_CODE, " Hash Function" , true })}));
416
+ }
417
+
418
+ string tex = get_tex (sections);
373
419
374
420
ofstream out (" contents.tex" );
375
421
if (out.is_open ()) out << tex;
@@ -380,65 +426,3 @@ int main(){
380
426
381
427
return 0 ;
382
428
}
383
-
384
-
385
-
386
- /*
387
- // #include <openssl/evp.h>
388
- // compute MD5 hash of a string
389
- string compute_md5_hash(const string& content, int size) {
390
- unsigned char digest[EVP_MAX_MD_SIZE];
391
- unsigned int digest_len;
392
-
393
- EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
394
- EVP_DigestInit_ex(mdctx, EVP_md5(), nullptr);
395
- EVP_DigestUpdate(mdctx, content.c_str(), content.size());
396
- EVP_DigestFinal_ex(mdctx, digest, &digest_len);
397
- EVP_MD_CTX_free(mdctx);
398
-
399
- char mdString[33];
400
- for (unsigned int i = 0; i < 16; i++)
401
- sprintf(&mdString[i*2], "%02x", (unsigned int)digest[i]);
402
-
403
- mdString[32] = '0円';
404
- return string(mdString).substr(0, size);
405
- }
406
-
407
- string get_hash_arquivo(string &s, int size, int l = 0, int r = 1e9) {
408
- stringstream ss(s);
409
- string content = "", line;
410
-
411
- // Lê apenas o intervalo especificado
412
- for (int i = 0; i <= r; i++){
413
- if (!getline(ss, line)) break;
414
- if (i >= l) content += line + "\n";
415
- }
416
- return compute_md5_hash(content, size);
417
- }
418
-
419
-
420
- // Process content and add hashes
421
- string get_file_hash(string& content){
422
- stringstream ss(content);
423
- string line, output = "";
424
- int depth = 0;
425
- stack<int> st;
426
-
427
- for(int line_idx = 0; getline(ss, line); line_idx++){
428
- int start_line = line_idx;
429
-
430
- for (char c : line)
431
- if (c == '{') depth++, st.push(line_idx); else
432
- if (c == '}') depth--, start_line = st.top(), st.pop();
433
-
434
- string hash = "";
435
- if(!is_comment(line)) hash = get_hash_arquivo(content, HASH_LEN, start_line, line_idx);
436
- else if(depth != 0) hash = string(HASH_LEN + 1, ' ');
437
-
438
- output += hash + " " + line + "\n";
439
- }
440
-
441
- return output;
442
- }
443
-
444
- */
0 commit comments