#ifndef UTIL_HPP #define UTIL_HPP #include #include #include #include #include #include #include #include #include #include #include "struc.hpp" extern std::string indenting_string; std::string cut_last(std::string const& in, char c); std::string basename(std::string const& in); std::string dirname(std::string const& in); inline bool is_dev_file(std::string const& filename) { return filename.substr(0,5) == "/dev/"; } std::string indent(int n); bool is_among(std::string const& in, std::vector const& values); std::vector split(std::string const& in, const char* splitters); std::vector split(std::string const& in, char c); std::string escape_str(std::string const& in); inline bool is_num(char c) { return (c >= '0' && c <= '9'); } inline bool is_alpha(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } inline bool is_alphanum(char c) { return is_alpha(c) || is_num(c); } template std::string strf( const std::string& format, Args ... args ) { size_t size = snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0' if( size <= 0 ) throw std::runtime_error( "Error during formatting." ); std::unique_ptr buf( new char[ size ] ); snprintf( buf.get(), size, format.c_str(), args ... ); return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside } template std::vector make_vector(Args ... args) { return std::vector( { args... } ); } template std::vector> sort_by_value(std::map const& in) { typedef std::pair pair_t; // create an empty vector of pairs std::vector ret; // copy key-value pairs from the map to the vector std::copy(in.begin(), in.end(), std::back_inserter>(ret)); // sort the vector by increasing order of its pair's second value // if second value are equal, order by the pair's first value std::sort(ret.begin(), ret.end(), [](const pair_t& l, const pair_t& r) { if (l.second != r.second) return l.second > r.second; return l.first > r.first; }); return ret; } inline bool is_in(char c, const char* set) { return strchr(set, c) != NULL; } template std::set prune_matching(std::map& in, std::regex re) { std::set ret; auto it=in.begin(); auto prev=in.end(); while(it!=in.end()) { if( std::regex_match(it->first, re) ) { ret.insert(it->first); in.erase(it); if(prev == in.end()) it = in.begin(); else { it = prev; it++; } } else { prev=it; it++; } } return ret; } template std::set map_to_set(std::map in) { std::set ret; for(auto it: in) { ret.insert(it.first); } return ret; } template void concat_sets(std::set& a, std::set const& b) { for(auto it: b) { a.insert( it ); } } template bool is_in_vector(T el, std::vector vec) { for(auto it: vec) if(it == el) return true; return false; } std::set prune_matching(std::set& in, std::regex re); std::string delete_brackets(std::string const& in); std::string concatargs(std::vector const& args); int _exec(std::string const& bin, std::vector const& args); std::string stringReplace(std::string subject, const std::string& search, const std::string& replace); std::string escape_chars(std::string subject, const char* chars); void printFormatError(format_error const& e, bool print_line=true); #endif //UTIL_HPP