<commit_before>/// \file kernel/userver.cc

//#define ENABLE_DEBUG_TRACES
#include <cassert>
#include <libport/compiler.hh>
#include <libport/csignal>
#include <libport/cstdlib>

#include <fstream>
#include <string>

// Include our header first to avoid duplicating some of its tricks.
#include <kernel/userver.hh>

#include <boost/assign/list_of.hpp>
#include <boost/bind.hpp>
#include <boost/checked_delete.hpp>
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>

#include <libport/backtrace.hh>
#include <libport/compiler.hh>
#include <libport/config.h>
#include <libport/cstdio>
#include <libport/detect-win32.h>
#include <libport/finally.hh>
#include <libport/foreach.hh>
#include <libport/lexical-cast.hh>
#include <libport/path.hh>
#include <libport/package-info.hh>
#include <libport/program-name.hh>
#include <libport/sysexits.hh>

#include <kernel/config.h>

#include <urbi/exit.hh>
#include <urbi/uobject.hh>
#include <urbi/usystem.hh>

#include <kernel/userver.hh>
#include <kernel/utypes.hh>

#include <ast/ast.hh>
#include <ast/nary.hh>

#include <object/object.hh>
#include <object/primitive.hh>
#include <object/root-classes.hh>
#include <object/symbols.hh>
#include <object/system.hh>

#include <runner/runner.hh>
#include <runner/shell.hh>
#include <runner/sneaker.hh>

#include <sched/scheduler.hh>

#include <kernel/connection-set.hh>
#include <kernel/server-timer.hh>
#include <kernel/ubanner.hh>
#include <kernel/ughostconnection.hh>
#include <kernel/uobject.hh>
#include <kernel/uqueue.hh>

using libport::program_name;

namespace kernel
{
  // Global server reference
  UServer *urbiserver = 0;

  // Buffers used to output data.
  /// Used by echo() & error().
  // FIXME: Because of this stupid hard limit, we can't produce
  // large outputs!  We should move to using C++.  Or some scheme
  // that is robust to the size of the message.
  // NOTE: Do not *ever* create an object of this type on the stack.
  // All instances must be marked as static. And the functions using
  // them will not be reentrant. You have been warned.
  typedef char buffer_type[8192];

  UServer::UServer(const char* mainName)
    : search_path(boost::assign::list_of
                  (std::string(libport::xgetenv("URBI_PATH")))
                  (std::string(libport::xgetenv("URBI_ROOT", URBI_ROOT))
                   + "/share/gostai"),
                  ":")
    , scheduler_(new sched::Scheduler(boost::bind(&UServer::getTime,
                                                  boost::ref(*this))))
    , mainName_(mainName)
    , stopall(false)
    , connections_(new kernel::ConnectionSet)
    , thread_id_(pthread_self())
  {
#if ! defined NDEBUG
    server_timer.start();
    server_timer.dump_on_destruction(std::cerr);
    TIMER_PUSH("server");
#endif
    urbiserver = this;
#ifndef WIN32
    // Use line buffering even when stdout is not a TTY.
    setlinebuf(stdout);
#endif
  }

  UErrorValue
  UServer::load_init_file(const char* fn)
  {
    DEBUG(("Loading %s...", fn));
    UErrorValue res = load_file(fn, ghost_->recv_queue_get());
    if (res == USUCCESS)
    {
      DEBUG(("done\n"));
      ghost_->new_data_added_get() = true;
    }
    else
      DEBUG (("not found\n"));
    return res;
  }

  static
  void
  init_error()
  {
    static bool ignore = getenv("IGNORE_URBI_U");
    if (!ignore)
    {
      boost::format fmt("%s: set IGNORE_URBI_U to ignore.");
      throw urbi::Exit(EX_OSFILE, str(fmt % program_name()));
    }
  }

  void
  UServer::xload_init_file(const char* fn)
  {
    if (load_init_file(fn) != USUCCESS)
    {
      std::cerr
        << program_name() << ": cannot load " << fn << "." << std::endl
        << program_name() << ": path: " << search_path << std::endl;
      init_error();
    }
  }

  void
  UServer::revision_check()
  {
    // Check that revision bw C++ and Urbi match.
    xload_init_file("urbi/package-info.u");

    // Force the processing until PackageInfo is defined.
    while (!object::system_class->slot_has(SYMBOL(PackageInfo)))
      work();
    object::rObject PackageInfo =
      object::system_class->slot_get(SYMBOL(PackageInfo));
    std::string urbi_rev =
      PackageInfo->slot_get(SYMBOL(revision)).get<std::string>();

    // C++ revision.
    std::string cxx_rev = package_info().get("revision");
    if (urbi_rev != cxx_rev)
    {
      std::cerr
        << program_name() << ": revison mismatch between C++ and Urbi." << std::endl
        << program_name() << ":   kernel revision: " << cxx_rev << std::endl
        << program_name() << ":   urbi.u revision: " << urbi_rev << std::endl;
      init_error();
    }
  }

#if !defined WIN32 && !defined _MSC_VER
  namespace
  {
    static void
    install_ice_catcher(void (*catcher)(int))
    {
      signal(SIGABRT, catcher);
      signal(SIGBUS,  catcher);
      signal(SIGSEGV, catcher);
    }<commit_msg>Disable ICE catcher if NO_ICE_CATCHER is set.<commit_after>/// \file kernel/userver.cc

//#define ENABLE_DEBUG_TRACES
#include <cassert>
#include <libport/compiler.hh>
#include <libport/csignal>
#include <libport/cstdlib>

#include <fstream>
#include <string>

// Include our header first to avoid duplicating some of its tricks.
#include <kernel/userver.hh>

#include <boost/assign/list_of.hpp>
#include <boost/bind.hpp>
#include <boost/checked_delete.hpp>
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>

#include <libport/backtrace.hh>
#include <libport/compiler.hh>
#include <libport/config.h>
#include <libport/cstdio>
#include <libport/detect-win32.h>
#include <libport/finally.hh>
#include <libport/foreach.hh>
#include <libport/lexical-cast.hh>
#include <libport/path.hh>
#include <libport/package-info.hh>
#include <libport/program-name.hh>
#include <libport/sysexits.hh>

#include <kernel/config.h>

#include <urbi/exit.hh>
#include <urbi/uobject.hh>
#include <urbi/usystem.hh>

#include <kernel/userver.hh>
#include <kernel/utypes.hh>

#include <ast/ast.hh>
#include <ast/nary.hh>

#include <object/object.hh>
#include <object/primitive.hh>
#include <object/root-classes.hh>
#include <object/symbols.hh>
#include <object/system.hh>

#include <runner/runner.hh>
#include <runner/shell.hh>
#include <runner/sneaker.hh>

#include <sched/scheduler.hh>

#include <kernel/connection-set.hh>
#include <kernel/server-timer.hh>
#include <kernel/ubanner.hh>
#include <kernel/ughostconnection.hh>
#include <kernel/uobject.hh>
#include <kernel/uqueue.hh>

using libport::program_name;

namespace kernel
{
  // Global server reference
  UServer *urbiserver = 0;

  // Buffers used to output data.
  /// Used by echo() & error().
  // FIXME: Because of this stupid hard limit, we can't produce
  // large outputs!  We should move to using C++.  Or some scheme
  // that is robust to the size of the message.
  // NOTE: Do not *ever* create an object of this type on the stack.
  // All instances must be marked as static. And the functions using
  // them will not be reentrant. You have been warned.
  typedef char buffer_type[8192];

  UServer::UServer(const char* mainName)
    : search_path(boost::assign::list_of
                  (std::string(libport::xgetenv("URBI_PATH")))
                  (std::string(libport::xgetenv("URBI_ROOT", URBI_ROOT))
                   + "/share/gostai"),
                  ":")
    , scheduler_(new sched::Scheduler(boost::bind(&UServer::getTime,
                                                  boost::ref(*this))))
    , mainName_(mainName)
    , stopall(false)
    , connections_(new kernel::ConnectionSet)
    , thread_id_(pthread_self())
  {
#if ! defined NDEBUG
    server_timer.start();
    server_timer.dump_on_destruction(std::cerr);
    TIMER_PUSH("server");
#endif
    urbiserver = this;
#ifndef WIN32
    // Use line buffering even when stdout is not a TTY.
    setlinebuf(stdout);
#endif
  }

  UErrorValue
  UServer::load_init_file(const char* fn)
  {
    DEBUG(("Loading %s...", fn));
    UErrorValue res = load_file(fn, ghost_->recv_queue_get());
    if (res == USUCCESS)
    {
      DEBUG(("done\n"));
      ghost_->new_data_added_get() = true;
    }
    else
      DEBUG (("not found\n"));
    return res;
  }

  static
  void
  init_error()
  {
    static bool ignore = getenv("IGNORE_URBI_U");
    if (!ignore)
    {
      boost::format fmt("%s: set IGNORE_URBI_U to ignore.");
      throw urbi::Exit(EX_OSFILE, str(fmt % program_name()));
    }
  }

  void
  UServer::xload_init_file(const char* fn)
  {
    if (load_init_file(fn) != USUCCESS)
    {
      std::cerr
        << program_name() << ": cannot load " << fn << "." << std::endl
        << program_name() << ": path: " << search_path << std::endl;
      init_error();
    }
  }

  void
  UServer::revision_check()
  {
    // Check that revision bw C++ and Urbi match.
    xload_init_file("urbi/package-info.u");

    // Force the processing until PackageInfo is defined.
    while (!object::system_class->slot_has(SYMBOL(PackageInfo)))
      work();
    object::rObject PackageInfo =
      object::system_class->slot_get(SYMBOL(PackageInfo));
    std::string urbi_rev =
      PackageInfo->slot_get(SYMBOL(revision)).get<std::string>();

    // C++ revision.
    std::string cxx_rev = package_info().get("revision");
    if (urbi_rev != cxx_rev)
    {
      std::cerr
        << program_name() << ": revison mismatch between C++ and Urbi." << std::endl
        << program_name() << ":   kernel revision: " << cxx_rev << std::endl
        << program_name() << ":   urbi.u revision: " << urbi_rev << std::endl;
      init_error();
    }
  }

#if !defined WIN32 && !defined _MSC_VER
  namespace
  {
    static void
    install_ice_catcher(void (*catcher)(int))
    {
      if (getenv("NO_ICE_CATCHER"))
        return;
      signal(SIGABRT, catcher);
      signal(SIGBUS,  catcher);
      signal(SIGSEGV, catcher);
    }
{'fraction_non_alphanumeric': 0.14995925020374898, 'fraction_numerical': 0.002241238793806031, 'mean_word_length': 3.2812908853030964, 'pattern_counts': {'":': 12, '<': 179, '<?xml version=': 0, '>': 109, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4515257', 'n_tokens_mistral': 3412, 'n_tokens_neox': 3341, 'n_words': 741}