pstring ppreprocessor::process(const pstring &contents) { pstringbuffer ret = ""; pstring_list_t lines(contents,"\n", false); UINT32 ifflag = 0; // 31 if levels int level = 0; std::size_t i=0; while (i<lines.size()) { pstring line = lines[i]; pstring lt = line.replace("\t"," ").trim(); // FIXME ... revise and extend macro handling if (lt.startsWith("#")) { pstring_list_t lti(lt, " ", true); if (lti[0].equals("#if")) { level++; std::size_t start = 0; lt = replace_macros(lt); pstring_list_t t = pstring_list_t::splitexpr(lt.substr(3).replace(" ",""), m_expr_sep); int val = expr(t, start, 0); if (val == 0) ifflag |= (1 << level); } else if (lti[0].equals("#ifdef")) { level++; if (get_define(lti[1]) == NULL) ifflag |= (1 << level); } else if (lti[0].equals("#ifndef")) { level++; if (get_define(lti[1]) != NULL) ifflag |= (1 << level); } else if (lti[0].equals("#else")) { ifflag ^= (1 << level); } else if (lti[0].equals("#endif")) { ifflag &= ~(1 << level); level--; } else if (lti[0].equals("#include")) { // ignore } else if (lti[0].equals("#pragma")) { if (ifflag == 0 && lti.size() > 3 && lti[1].equals("NETLIST")) { if (lti[2].equals("warning")) error("NETLIST: " + catremainder(lti, 3, " ")); } } else if (lti[0].equals("#define")) { if (ifflag == 0) { if (lti.size() != 3) error(pstring::sprintf("PREPRO: only simple defines allowed: %s", line.cstr())); m_defines.add(define_t(lti[1], lti[2])); } } else error(pstring::sprintf("unknown directive on line %" SIZETFMT ": %s\n", SIZET_PRINTF(i), line.cstr())); } else { //if (ifflag == 0 && level > 0) // fprintf(stderr, "conditional: %s\n", line.cstr()); lt = replace_macros(lt); if (ifflag == 0) { ret.cat(lt); ret.cat("\n"); } } i++; } return pstring(ret.cstr()); }
pstring ppreprocessor::process_line(const pstring &line) { pstring lt = line.replace("\t"," ").trim(); pstringbuffer ret; m_lineno++; // FIXME ... revise and extend macro handling if (lt.startsWith("#")) { pstring_vector_t lti(lt, " ", true); if (lti[0].equals("#if")) { m_level++; std::size_t start = 0; lt = replace_macros(lt); pstring_vector_t t(lt.substr(3).replace(" ",""), m_expr_sep); int val = static_cast<int>(expr(t, start, 0)); if (val == 0) m_ifflag |= (1 << m_level); } else if (lti[0].equals("#ifdef")) { m_level++; if (get_define(lti[1]) == nullptr) m_ifflag |= (1 << m_level); } else if (lti[0].equals("#ifndef")) { m_level++; if (get_define(lti[1]) != nullptr) m_ifflag |= (1 << m_level); } else if (lti[0].equals("#else")) { m_ifflag ^= (1 << m_level); } else if (lti[0].equals("#endif")) { m_ifflag &= ~(1 << m_level); m_level--; } else if (lti[0].equals("#include")) { // ignore } else if (lti[0].equals("#pragma")) { if (m_ifflag == 0 && lti.size() > 3 && lti[1].equals("NETLIST")) { if (lti[2].equals("warning")) error("NETLIST: " + catremainder(lti, 3, " ")); } } else if (lti[0].equals("#define")) { if (m_ifflag == 0) { if (lti.size() != 3) error("PREPRO: only simple defines allowed: " + line); m_defines.insert({lti[1], define_t(lti[1], lti[2])}); } } else error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(line)); } else { lt = replace_macros(lt); if (m_ifflag == 0) { ret.cat(lt); } } return ret; }
token_list tokenize(std::string source_) { std::list<token> token_stream; std::string token_str; bool in_string = false; bool is_comment_line = false; bool is_comment_block = false; std::string string_quote_type = "'"; std::regex replace_macros("[a-zA-Z0-9_]+?\\([a-zA-Z0-9_\\(\\), ]*?\\)"); source_ = std::regex_replace(source_, replace_macros, "MACRO_REPLACED_BY_TOKENIZE"); //std::cout << source_; for (std::string::size_type stream_pos = 0; stream_pos < source_.size(); ++stream_pos) { std::string cur_char = source_.substr(stream_pos, 1); if (!in_string) { if (cur_char == "\"" || cur_char == "'" || cur_char == " " || cur_char == "\t" || cur_char == "+" || cur_char == "-" || cur_char == "*" || cur_char == "/" || cur_char == ">" || cur_char == "<" || cur_char == "=" || cur_char == "]" || cur_char == "[" || cur_char == "(" || cur_char == ")" || cur_char == "}" || cur_char == "{" || cur_char == "," || cur_char == "!" || cur_char == "." || cur_char == ":" || cur_char == ";" ) { if (token_str != "") { if (!is_comment_line && !is_comment_block) { token new_token; new_token.val = token_str; if (is_number(token_str)) { new_token.type = type::SCALAR; } else { new_token.type = type::LITERAL; } new_token.stream_pos = stream_pos - token_str.length(); if (token_str[0] == '_') new_token.type = type::LOCALVARIABLE; if (is_reserved_word(token_str)) new_token.type = type::SCRIPTCOMMAND; token_stream.push_back(new_token); } } if (cur_char == "+" || cur_char == "-" || cur_char == "*" || cur_char == "/" || cur_char == ">" || cur_char == "<" || cur_char == "=" || cur_char == "]" || cur_char == "[" || cur_char == "(" || cur_char == ")" || cur_char == "}" || cur_char == "{" || cur_char == "," || cur_char == "!" || cur_char == "." || cur_char == ":" || cur_char == ";" ) { bool skip = false; if (cur_char == ">" || cur_char == "<" || cur_char == "!" || cur_char == "=" ) { if (source_.substr(stream_pos + 1, 1) == "=") { skip = true; cur_char += "="; } } if (cur_char == ":") { if (source_.substr(stream_pos + 1, 1) == ":") { skip = true; cur_char += ":"; } } if (cur_char == "/") { if (source_.substr(stream_pos + 1, 1) == "*") { skip = true; cur_char += "*"; is_comment_block = true; } } if (cur_char == "/") { if (source_.substr(stream_pos + 1, 1) == "/") { skip = true; cur_char += "/"; is_comment_line = true; } } if (!is_comment_line && !is_comment_block) { token operator_token; operator_token.val = cur_char; operator_token.stream_pos = stream_pos; operator_token.type = type::OPERATOR; if (cur_char == ";") { operator_token.type = type::ENDOFSTATEMENT; } token_stream.push_back(operator_token); } if (cur_char == "*") { if (source_.substr(stream_pos + 1, 1) == "/") { skip = true; cur_char += "/"; is_comment_block = false; token_str = ""; } } if (skip) { stream_pos++; } } token_str = ""; if (cur_char == "\"") { token_str = "\"" + token_str; } if (cur_char == "'") { token_str = "'" + token_str; } } else { if ( token_str == "<=" || token_str == ">=" || token_str == "!=" || token_str == "::" || token_str == "==" ) { if (!is_comment_line && !is_comment_block) { token new_token; new_token.val = token_str; new_token.stream_pos = stream_pos - token_str.length(); new_token.type = type::OPERATOR; token_stream.push_back(new_token); } token_str = ""; } else { if (cur_char != "\n") { token_str += cur_char; } else { if (!is_comment_line && !is_comment_block && token_str!= "") { token new_token; new_token.val = token_str; if (is_number(token_str)) { new_token.type = type::SCALAR; } else { new_token.type = type::LITERAL; } new_token.stream_pos = stream_pos - token_str.length(); if (token_str[0] == '_') new_token.type = type::LOCALVARIABLE; if (is_reserved_word(token_str)) new_token.type = type::SCRIPTCOMMAND; token_stream.push_back(new_token); } if (is_comment_line) { is_comment_line = false; token_str = ""; } } } } } else { token_str += cur_char; } if (!is_comment_line && !is_comment_block) { if (cur_char == "\"" || cur_char == "'") { if (!in_string) { string_quote_type = cur_char; in_string = true; } else if(in_string && cur_char == string_quote_type) { if (source_.substr(stream_pos + 1, 1) == string_quote_type) { token_str += string_quote_type; stream_pos++; } else { in_string = false; } } } } } return token_stream; }
void logger::init(const config_tree& a_cfg, const sigset_t* a_ignore_signals, bool a_install_finalizer) { if (m_initialized) throw std::runtime_error("Logger already initialized!"); std::lock_guard<std::mutex> guard(m_mutex); do_finalize(); try { m_show_location = a_cfg.get<bool> ("logger.show-location", m_show_location); m_show_fun_namespaces = a_cfg.get<int> ("logger.show-fun-namespaces", m_show_fun_namespaces); m_show_category = a_cfg.get<bool> ("logger.show-category", m_show_category); m_show_ident = a_cfg.get<bool> ("logger.show-ident", m_show_ident); m_show_thread = a_cfg.get<bool> ("logger.show-thread", m_show_thread); m_fatal_kill_signal = a_cfg.get<int> ("logger.fatal-kill-signal",m_fatal_kill_signal); m_ident = a_cfg.get<std::string>("logger.ident", m_ident); m_ident = replace_macros(m_ident); std::string ts = a_cfg.get<std::string>("logger.timestamp", "time-usec"); m_timestamp_type = parse_stamp_type(ts); std::string levs = a_cfg.get<std::string>("logger.levels", ""); if (!levs.empty()) set_level_filter(static_cast<log_level>(parse_log_levels(levs))); std::string ls = a_cfg.get<std::string>("logger.min-level-filter", "info"); if (!levs.empty() && !ls.empty()) std::runtime_error ("Either 'levels' or 'min-level-filter' option is permitted!"); set_min_level_filter(parse_log_level(ls)); long timeout_ms = a_cfg.get<int> ("logger.wait-timeout-ms", 1000); m_wait_timeout = timespec{timeout_ms / 1000, timeout_ms % 1000 * 1000000L}; m_sched_yield_us = a_cfg.get<long> ("logger.sched-yield-us", -1); m_silent_finish = a_cfg.get<bool> ("logger.silent-finish", false); m_block_signals = a_cfg.get<bool> ("logger.block-signals", true); if ((int)m_timestamp_type < 0) throw std::runtime_error("Invalid timestamp type: " + ts); // Install crash signal handlers // (SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM) if (a_cfg.get("logger.handle-crash-signals", true)) { sigset_t sset = sig_members_parse (a_cfg.get("logger.handle-crash-signals.signals",""), UTXX_SRC); // Remove signals from the sset that are handled externally if (a_ignore_signals) for (uint i=1; i < sig_names_count(); ++i) if (sigismember(a_ignore_signals, i)) sigdelset(&sset, i); if (install_sighandler(true, &sset)) { auto old = m_crash_sigset.exchange(new sigset_t(sset)); if (!old) delete old; } } //logger_impl::msg_info info(NULL, 0); //query_timestamp(info); logger_impl_mgr& lim = logger_impl_mgr::instance(); std::lock_guard<std::mutex> guard(lim.mutex()); // Check the list of registered implementations. If corresponding // configuration section is found, initialize the implementation. for(logger_impl_mgr::impl_map_t::iterator it=lim.implementations().begin(); it != lim.implementations().end(); ++it) { std::string path = std::string("logger.") + it->first; if (a_cfg.get_child_optional(path)) { // Determine if implementation of this type is already // registered with the logger bool found = false; for(implementations_vector::iterator im = m_implementations.begin(), iend = m_implementations.end(); im != iend; ++im) if (it->first == (*im)->name()) { found = true; break; } if (found) throw badarg_error("Implementation '", it->first, "' is already registered with the logger!"); // A call to it->second() creates a logger_impl* pointer. // We need to call implementation's init function that may throw, // so use RAII to guarantee proper cleanup. logger_impl_mgr::impl_callback_t& f = it->second; m_implementations.emplace_back( f(it->first.c_str()) ); auto& i = m_implementations.back(); i->set_log_mgr(this); i->init(a_cfg); } } m_initialized = true; m_abort = false; m_thread.reset(new std::thread([this]() { this->run(); })); if (!m_finalizer_installed && a_install_finalizer) { atexit(&finalize_logger_at_exit); m_finalizer_installed = true; } } catch (std::runtime_error& e) { if (m_error) m_error(e.what()); else throw; } }
pstring ppreprocessor::process_line(pstring line) { bool line_cont = plib::right(line, 1) == "\\"; if (line_cont) line = plib::left(line, line.size() - 1); if (m_state == LINE_CONTINUATION) m_line += line; else m_line = line; if (line_cont) { m_state = LINE_CONTINUATION; return ""; } else m_state = PROCESS; line = process_comments(m_line); pstring lt = plib::trim(plib::replace_all(line, pstring("\t"), pstring(" "))); pstring ret; // FIXME ... revise and extend macro handling if (plib::startsWith(lt, "#")) { std::vector<pstring> lti(psplit(lt, " ", true)); if (lti[0] == "#if") { m_level++; std::size_t start = 0; lt = replace_macros(lt); std::vector<pstring> t(psplit(replace_all(lt.substr(3), pstring(" "), pstring("")), m_expr_sep)); int val = static_cast<int>(expr(t, start, 255)); if (val == 0) m_ifflag |= (1 << m_level); } else if (lti[0] == "#ifdef") { m_level++; if (get_define(lti[1]) == nullptr) m_ifflag |= (1 << m_level); } else if (lti[0] == "#ifndef") { m_level++; if (get_define(lti[1]) != nullptr) m_ifflag |= (1 << m_level); } else if (lti[0] == "#else") { m_ifflag ^= (1 << m_level); } else if (lti[0] == "#endif") { m_ifflag &= ~(1 << m_level); m_level--; } else if (lti[0] == "#include") { // ignore } else if (lti[0] == "#pragma") { if (m_ifflag == 0 && lti.size() > 3 && lti[1] == "NETLIST") { if (lti[2] == "warning") error("NETLIST: " + catremainder(lti, 3, " ")); } } else if (lti[0] == "#define") { if (m_ifflag == 0) { if (lti.size() != 3) error("PREPRO: only simple defines allowed: " + line); m_defines.insert({lti[1], define_t(lti[1], lti[2])}); } } else { if (m_ifflag == 0) error(pfmt("unknown directive on line {1}: {2}")(m_lineno)(replace_macros(line))); } } else { lt = replace_macros(lt); if (m_ifflag == 0) ret += lt; } return ret; }