Created
December 27, 2016 08:29
-
-
Save yumetodo/43a0a3942199d17532e2b576880d2a46 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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