Hello!↵
↵
After seeing the recent hype towards debugging utils and code snippets usage and what not, and due to the fact that I had 30 minutes of free time to spend this afternoon, I decided to write a small Python script that pre-compiles multiple files into one big file for Codeforces submission.↵
↵
The tool is here: https://pastebin.com/CR0mJXbRc4dS4Pik (Python 3 required)↵
↵
Basically the tool does these steps:↵
↵
- remove the ``#include <bla>`` lines from the code↵
- run the GCC preprocessor on the code↵
- add the ``#include <bla>`` lines back↵
- run some cleanup routine (optional)↵
↵
In order to use this script, copy it somewhere (preferably in your PATH directory), and run it using:↵
``/path/to/scr.py file.cpp [ARGS]``↵
The ``ARGS`` are similar to the ones you would give to your ``g++`` command.↵
↵
For example, let's say we have three files:↵
↵
<spoiler summary="FILE: debug.hpp">↵
```↵
#pragma once ↵
↵
#ifdef DEBUG↵
↵
int recur_depth = 0;↵
↵
#define dbg(x) {++recur_depth; auto x_=x; --recur_depth; cerr<<string(recur_depth, '\t')<<"\e[91m"<<__func__<<":"<<__LINE__<<"\t"<<#x<<" = "<<x_<<"\e[39m"<<endl;}↵
↵
template<typename Ostream, typename Cont>↵
typename std::enable_if<std::is_same<Ostream,std::ostream>::value, Ostream&>::type ↵
operator<<(Ostream& os, const Cont& v){↵
os<<"[";↵
bool first = true;↵
for(auto& x:v){↵
if (!first) ↵
os << ", ";↵
os << x;↵
first = false;↵
}↵
return os<<"]";↵
}↵
↵
template<typename Ostream, typename ...Ts>↵
Ostream& operator<<(Ostream& os, const std::pair<Ts...>& p){↵
return os<<"{"<<p.first<<", "<<p.second<<"}";↵
}↵
↵
#else↵
#define dbg(x)↵
#endif↵
```↵
</spoiler>↵
↵
<spoiler summary="FILE: dsu.hpp">↵
```↵
#pragma once ↵
↵
using namespace std;↵
↵
struct DSU {↵
vector<int> link;↵
↵
DSU(int n) : link(n, -1) {}↵
↵
int Find(int x) { ↵
if (link[x] == -1) return x;↵
return link[x] = Find(link[x]);↵
}↵
↵
void Union(int a, int b) {↵
a = Find(a); b = Find(b);↵
if (a != b) link[a] = b;↵
}↵
};↵
```↵
</spoiler>↵
↵
<spoiler summary="FILE: sol.cpp">↵
```↵
#include <bits/stdc++.h>↵
#include "debug.hpp"↵
#include "dsu.hpp"↵
↵
using namespace std;↵
↵
int main() {↵
int n; cin >> n;↵
DSU dsu(n);↵
dbg(dsu.link);↵
↵
return 0;↵
}↵
```↵
</spoiler>↵
↵
Output of ``/path/to/scr.py sol.cpp``:↵
↵
<spoiler summary="OUTPUT">↵
```↵
#include <bits/stdc++.h>↵
↵
using namespace std;↵
↵
struct DSU {↵
vector<int> link;↵
↵
DSU(int n) : link(n, -1) {}↵
↵
int Find(int x) {↵
if (link[x] == -1) return x;↵
return link[x] = Find(link[x]);↵
}↵
↵
void Union(int a, int b) {↵
a = Find(a); b = Find(b);↵
if (a != b) link[a] = b;↵
}↵
};↵
↵
int main() {↵
int n; cin >> n;↵
DSU dsu(n);↵
↵
return 0;↵
}↵
```↵
</spoiler>↵
↵
Output of ``/path/to/scr.py sol.cpp -DDEBUG``:↵
↵
<spoiler summary="OUTPUT">↵
```↵
#include <bits/stdc++.h>↵
↵
int recur_depth = 0;↵
↵
template<typename Ostream, typename Cont>↵
typename std::enable_if<std::is_same<Ostream,std::ostream>::value, Ostream&>::type↵
operator<<(Ostream& os, const Cont& v){↵
os<<"[";↵
bool first = true;↵
for(auto& x:v){↵
if (!first)↵
os << ", ";↵
os << x;↵
first = false;↵
}↵
return os<<"]";↵
}↵
↵
template<typename Ostream, typename ...Ts>↵
Ostream& operator<<(Ostream& os, const std::pair<Ts...>& p){↵
return os<<"{"<<p.first<<", "<<p.second<<"}";↵
}↵
↵
using namespace std;↵
↵
struct DSU {↵
vector<int> link;↵
↵
DSU(int n) : link(n, -1) {}↵
↵
int Find(int x) {↵
if (link[x] == -1) return x;↵
return link[x] = Find(link[x]);↵
}↵
↵
void Union(int a, int b) {↵
a = Find(a); b = Find(b);↵
if (a != b) link[a] = b;↵
}↵
};↵
↵
int main() {↵
int n; cin >> n;↵
DSU dsu(n);↵
{++recur_depth; auto x_=dsu.link; --recur_depth; cerr<<string(recur_depth, '\t')<<"\e[91m"<<__func__<<":"<<9<<"\t"<<"dsu.link"<<" = "<<x_<<"\e[39m"<<endl;};↵
↵
return 0;↵
}↵
```↵
</spoiler>↵
↵
The main idea is that it merges all your ``#include "bla"`` files (not the ``#include <bla>`` ones, though), and replaces all the ``#define``s and other preprocessor instructions. ↵
↵
Let me know what you think! The tool should work fine in UNIX-based systems (Mac OS X, Linux). I would be happy if someone could test/port this tool for Windows. I think one cool thing about this tool is that it pre-compiles all the ``#define``s, so that most of the output code would look more standardized (C++-ish).↵
↵
I would personally probably not use this tool too much, as my general approach is to copy-paste implementations and tweak them to the specific problem, but I know a lot of people prefer to use them as black boxes, so this might be useful.↵
↵
↵
↵
After seeing the recent hype towards debugging utils and code snippets usage and what not, and due to the fact that I had 30 minutes of free time to spend this afternoon, I decided to write a small Python script that pre-compiles multiple files into one big file for Codeforces submission.↵
↵
The tool is here: https://pastebin.com/
↵
Basically the tool does these steps:↵
↵
- remove the ``#include <bla>`` lines from the code↵
- run the GCC preprocessor on the code↵
- add the ``#include <bla>`` lines back↵
- run some cleanup routine (optional)↵
↵
In order to use this script, copy it somewhere (preferably in your PATH directory), and run it using:↵
``/path/to/scr.py file.cpp [ARGS]``↵
The ``ARGS`` are similar to the ones you would give to your ``g++`` command.↵
↵
For example, let's say we have three files:↵
↵
<spoiler summary="FILE: debug.hpp">↵
```↵
#pragma once ↵
↵
#ifdef DEBUG↵
↵
int recur_depth = 0;↵
↵
#define dbg(x) {++recur_depth; auto x_=x; --recur_depth; cerr<<string(recur_depth, '\t')<<"\e[91m"<<__func__<<":"<<__LINE__<<"\t"<<#x<<" = "<<x_<<"\e[39m"<<endl;}↵
↵
template<typename Ostream, typename Cont>↵
typename std::enable_if<std::is_same<Ostream,std::ostream>::value, Ostream&>::type ↵
operator<<(Ostream& os, const Cont& v){↵
os<<"[";↵
bool first = true;↵
for(auto& x:v){↵
if (!first) ↵
os << ", ";↵
os << x;↵
first = false;↵
}↵
return os<<"]";↵
}↵
↵
template<typename Ostream, typename ...Ts>↵
Ostream& operator<<(Ostream& os, const std::pair<Ts...>& p){↵
return os<<"{"<<p.first<<", "<<p.second<<"}";↵
}↵
↵
#else↵
#define dbg(x)↵
#endif↵
```↵
</spoiler>↵
↵
<spoiler summary="FILE: dsu.hpp">↵
```↵
#pragma once ↵
↵
using namespace std;↵
↵
struct DSU {↵
vector<int> link;↵
↵
DSU(int n) : link(n, -1) {}↵
↵
int Find(int x) { ↵
if (link[x] == -1) return x;↵
return link[x] = Find(link[x]);↵
}↵
↵
void Union(int a, int b) {↵
a = Find(a); b = Find(b);↵
if (a != b) link[a] = b;↵
}↵
};↵
```↵
</spoiler>↵
↵
<spoiler summary="FILE: sol.cpp">↵
```↵
#include <bits/stdc++.h>↵
#include "debug.hpp"↵
#include "dsu.hpp"↵
↵
using namespace std;↵
↵
int main() {↵
int n; cin >> n;↵
DSU dsu(n);↵
dbg(dsu.link);↵
↵
return 0;↵
}↵
```↵
</spoiler>↵
↵
Output of ``/path/to/scr.py sol.cpp``:↵
↵
<spoiler summary="OUTPUT">↵
```↵
#include <bits/stdc++.h>↵
↵
using namespace std;↵
↵
struct DSU {↵
vector<int> link;↵
↵
DSU(int n) : link(n, -1) {}↵
↵
int Find(int x) {↵
if (link[x] == -1) return x;↵
return link[x] = Find(link[x]);↵
}↵
↵
void Union(int a, int b) {↵
a = Find(a); b = Find(b);↵
if (a != b) link[a] = b;↵
}↵
};↵
↵
int main() {↵
int n; cin >> n;↵
DSU dsu(n);↵
↵
return 0;↵
}↵
```↵
</spoiler>↵
↵
Output of ``/path/to/scr.py sol.cpp -DDEBUG``:↵
↵
<spoiler summary="OUTPUT">↵
```↵
#include <bits/stdc++.h>↵
↵
int recur_depth = 0;↵
↵
template<typename Ostream, typename Cont>↵
typename std::enable_if<std::is_same<Ostream,std::ostream>::value, Ostream&>::type↵
operator<<(Ostream& os, const Cont& v){↵
os<<"[";↵
bool first = true;↵
for(auto& x:v){↵
if (!first)↵
os << ", ";↵
os << x;↵
first = false;↵
}↵
return os<<"]";↵
}↵
↵
template<typename Ostream, typename ...Ts>↵
Ostream& operator<<(Ostream& os, const std::pair<Ts...>& p){↵
return os<<"{"<<p.first<<", "<<p.second<<"}";↵
}↵
↵
using namespace std;↵
↵
struct DSU {↵
vector<int> link;↵
↵
DSU(int n) : link(n, -1) {}↵
↵
int Find(int x) {↵
if (link[x] == -1) return x;↵
return link[x] = Find(link[x]);↵
}↵
↵
void Union(int a, int b) {↵
a = Find(a); b = Find(b);↵
if (a != b) link[a] = b;↵
}↵
};↵
↵
int main() {↵
int n; cin >> n;↵
DSU dsu(n);↵
{++recur_depth; auto x_=dsu.link; --recur_depth; cerr<<string(recur_depth, '\t')<<"\e[91m"<<__func__<<":"<<9<<"\t"<<"dsu.link"<<" = "<<x_<<"\e[39m"<<endl;};↵
↵
return 0;↵
}↵
```↵
</spoiler>↵
↵
The main idea is that it merges all your ``#include "bla"`` files (not the ``#include <bla>`` ones, though), and replaces all the ``#define``s and other preprocessor instructions. ↵
↵
Let me know what you think! The tool should work fine in UNIX-based systems (Mac OS X, Linux). I would be happy if someone could test/port this tool for Windows. I think one cool thing about this tool is that it pre-compiles all the ``#define``s, so that most of the output code would look more standardized (C++-ish).↵
↵
I would personally probably not use this tool too much, as my general approach is to copy-paste implementations and tweak them to the specific problem, but I know a lot of people prefer to use them as black boxes, so this might be useful.↵
↵
↵