My ghetto solution, with a consecutive-blank-lines-stripper -
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include <cctype>
const int max_length = 1024*1024*10; //10 MB
int main(int argc, char **argv) {
int file_length = 0;
char *buffer = new char[max_length];
std::string out_data;
std::ifstream in_file(argv[1], std::ios::in | std::ios::binary);
if (!in_file) {
std::cerr << "Error opening file: " << argv[1] << std::endl;
return 1;
}
if (in_file.read(buffer, max_length-1)) { //if the read was successful without hitting an EOF...
std::cerr << "File too big." << std::endl;
return 1;
}
file_length = in_file.gcount();
buffer[file_length] = 0;
std::string in_data(buffer); //make it a string so we have nice functions to play with
//first replace every "\r" by space
for (int i = 0; i < in_data.size(); ++i) {
if (in_data[i] == '\r') {
in_data[i] = ' ';
}
}
int state = 0; //0 = normal, 1 = ignore until end of line, 2 = ignore until "*/", 3 = ignore until "#endif"
int skip_next = 0;
for (int i = 0; i < in_data.size(); ++i) {
if (skip_next) {
--skip_next;
continue;
}
switch(state) {
case 0:
if ((i + 2 <= in_data.size()) && (in_data.substr(i, 2) == "//")) {
state = 1;
} else if ((i + 2 <= in_data.size()) && (in_data.substr(i, 2) == "/*")) {
state = 2;
} else if ((i + 5 <= in_data.size()) && (in_data.substr(i, 5) == "#if 0")) {
state = 3;
} else {
out_data.push_back(in_data[i]);
}
break;
case 1:
if (in_data[i] == '\n') {
out_data.push_back('\n');
state = 0;
}
break;
case 2:
if ((i + 2 <= in_data.size()) && (in_data.substr(i, 2) == "*/")) {
out_data.push_back('\n');
state = 0;
skip_next = 1;
}
break;
case 3:
if ((i + 6 <= in_data.size()) && (in_data.substr(i, 6) == "#endif")) {
out_data.push_back('\n');
state = 0;
skip_next = 5;
}
break;
default:
assert(false);
}
}
int n_count = 0;
for (int i = 0; i < out_data.size(); ++i) {
if (n_count > 1 && (out_data[i] == '\n' || out_data[i] == '\t' || out_data[i] == ' ')) {
continue;
} else {
if (out_data[i] != '\t' && out_data[i] != '\n' && out_data[i] != ' ') {
if (n_count > 1) { //get all the junk we threw away back!
int j = i;
while (out_data[j] != '\n') {
--j;
}
for (++j; j < i; ++j) {
std::cout << out_data[j];
}
}
n_count = 0;
}
if (out_data[i] == '\n') {
++n_count;
}
std::cout << out_data[i];
}
}
}
It's unbreakable until you try to break it .
EDIT: code edited for the consecutive-blank-lines-stripper.