Skip to content

Instantly share code, notes, and snippets.

@yumetodo
Created December 27, 2016 08:29
Show Gist options
  • Save yumetodo/43a0a3942199d17532e2b576880d2a46 to your computer and use it in GitHub Desktop.
Save yumetodo/43a0a3942199d17532e2b576880d2a46 to your computer and use it in GitHub Desktop.
#include <iostream>
#include "string_split.hpp"
#include <vector>
#include <algorithm>
void print_out(std::ostream os, const std::vector<std::string>& v){
constexpr std::size_t line_length_limit = 117;
std::string tmp;
tmp.reserve(line_length_limit);
bool is_first = true;
for(auto&& s : v){
if(s.size() < line_length_limit && tmp.size() + s.size() + 5 < line_length_limit){
tmp.reserve(std::max(line_length_limit, tmp.size() + s.size() + 1));
tmp += ' ';
tmp += s;
}
else{
if(!is_first){
os << " +" << std::endl;
}
else{
is_first = false;
}
if(tmp.empty()){
os << '\'' << s << '\'' << std::flush;
}
else{
os << '\'' << tmp << '\'' << std::flush;
tmp.clear();
}
}
}
os << '\'' << tmp << '\'' << std::endl;
}
inline std::size_t find_block_comment_last(const std::string& s, std::size_t first_pos = 0){
const auto block_comment_last = s.find("*/", first_pos);
return (std::string::npos == block_comment_last) ? std::string::npos : block_comment_last + 2;
}
inline std::size_t find_raw_string_literal_r_char_sequence_front(const std::string& s, std::string& delimiter, std::size_t raw_string_literal_front){
constexpr const char* d_char = R"(abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_{}[]#<>%:;.?*+-/^&|~!=,"’)";
const auto raw_string_literal_r_char_sequence_front = s.find_first_not_of(d_char, raw_string_literal_front + 2);
if(std::string::npos == raw_string_literal_r_char_sequence_front || '(' != s[raw_string_literal_r_char_sequence_front]){
throw std::invalid_argument("iregal raw string literal detect.");
}
delimiter = ')' + s.substr(raw_string_literal_front + 2, raw_string_literal_r_char_sequence_front - raw_string_literal_front - 3) + '"';
return raw_string_literal_r_char_sequence_front;
}
inline std::size_t find_raw_string_literal_last(const std::string& s, const std::string& delimiter, std::size_t first_pos = 0){
const auto raw_string_literal_last = s.find(delimiter, first_pos);
return (std::string::npos == block_comment_last) ? std::string::npos : block_comment_last + delimiter.size();
}
void erase_string_literal(std::string& s){
for(
auto literal_first_pos = s.find_first_of('"');
std::string::npos != literal_first_pos;
literal_first_pos = s.find_first_of('"', literal_first_pos)
){
std::size_t literal_last_pos;
for(
literal_last_pos = s.find_first_of('"', literal_first_pos);
std::string::npos == literal_last_pos || '\'' == s[literal_last_pos - 1] || '\\' == s[literal_last_pos - 1];
literal_last_pos = s.find_first_of('"', literal_last_pos);
){
if(std::string::npos == literal_last_pos) throw std::runtime_error("invalid token detect.");
}
s.erase(literal_first_pos, literal_last_pos - literal_first_pos + 1);
}
}
inline bool find_block_comment_last_and_remove(std::string& s, bool& in_block_comment, std::size_t block_comment_front_pos = 0){
const auto block_comment_last_pos = find_block_comment_last(buf, block_comment_front_pos);
if(std::string::npos == block_comment_last_pos){
return false;
}
else{
buf.erase(block_comment_front_pos, block_comment_last_pos);
in_block_comment = false;
return true;
}
}
inline bool find_raw_string_literal_last_and_remove(std::string& s, bool& in_raw_string_literal, std::size_t raw_string_literal_front_pos = 0){
const auto raw_string_literal_last_pos = find_raw_string_literal_last(buf, raw_string_literal_front_pos);
if(std::string::npos == raw_string_literal_last_pos){
return false;
}
else{
buf.erase(raw_string_literal_front_pos, raw_string_literal_last_pos);
in_raw_string_literal = false;
return true;
}
}
int main(void){
using std::string;
std::vector<string> re;
bool in_block_comment = false:
bool in_raw_string_literal = false;
string raw_string_literal_last;
for(string buf; std::getline(std::cin, buf);){
if(in_block_comment){
if(!find_block_comment_last_and_remove(s, in_block_comment)) continue;
}
else if(in_raw_string_literal){
if(!find_raw_string_literal_last_and_remove(s, in_raw_string_literal)) continue;
}
const auto preprocesser_directive_pos = buf.find_first_of('#');
if(string::npos == preprocesser_directive_pos) continue;
auto block_comment_first_pos = buf.find("/*");
auto raw_string_literal_front_pos = s.find(R"(R")");
bool block_comment_possibility = (string::npos != block_comment_first_pos && block_comment_first_pos < preprocesser_directive_pos);
bool raw_string_literal_possibility = (string::npos != block_comment_first_pos && block_comment_first_pos < preprocesser_directive_pos);
if(block_comment_possibility && raw_string_literal_possibility){
if(block_comment_first_pos < raw_string_literal_front_pos){
if(!find_block_comment_last_and_remove(s, in_block_comment, block_comment_first_pos)) continue;
}
else{
const auto raw_string_literal_r_char_sequence_front = find_raw_string_literal_r_char_sequence_front(buf, raw_string_literal_last, raw_string_literal_front_pos);
if(!find_raw_string_literal_last_and_remove(s, in_raw_string_literal, raw_string_literal_r_char_sequence_front)) continue;
}
}
const auto first_not_space_pos = buf.find_first_not_of(' ', preprocesser_directive_pos + 1);
const auto define_pos = buf.find("define", preprocesser_directive_pos + 1);
//'#' + define みたいなtokenを弾く
if(std::string::npos == define_pos && first_not_space_pos != define_pos) continue;
buf.erase(0, define_pos);
re.push_back(std::move(buf) | split(' ')[1] | split('(') >> front());
}
print_out(std::cout, re);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment