<commit_before>#include "funkeymonkeymodule.h"
#include "evdevdevice.h"
#include "funkeymonkeymoduleloader.h"
#include "cxxopts.hpp"

#include <iostream>
#include <cstdlib>

#include <memory.h>
#include <signal.h>

volatile sig_atomic_t done = 0;

void term(int)
{
  done = 1;
}

int main(int argc, char** argv)
{
  cxxopts::Options options(argv[0], " - A evdev/uinput wrangler");
  options.add_options()
    ("d,device", "Input device to read from, eg. /dev/input/event0",
     cxxopts::value<std::string>(), "PATH")
    ("p,plugin", "Path to plugin", cxxopts::value<std::string>(), "PATH")
    ("g,grab", "Grab the input device, preventing others from accessing it")
    ("h,help", "Print help");

  if(argc == 1)
  {
    std::cout << options.help({"", "Group"}) << std::endl;
    return EXIT_SUCCESS;
  }

  try
  {
    options.parse(argc, argv);
  }
  catch(cxxopts::OptionException e)
  {
    std::cerr << "ERROR: parsing options failed: " << e.what() << std::endl;
    return EXIT_FAILURE;
  }

  if(options.count("h"))
  {
    std::cout << options.help({"", "Group"}) << std::endl;
    return EXIT_SUCCESS;
  }

  if(options.count("d") != 1)
  {
    std::cerr << "ERROR: exactly one device is required" << std::endl;
    return EXIT_FAILURE;
  }

  if(options.count("p") != 1)
  {
    std::cerr << "ERROR: exactly one plugin is required" << std::endl;
    return EXIT_FAILURE;
  }

  EvdevDevice evdev(options["d"].as<std::string>());

  if(!evdev.ready())
  {
    std::cerr << "ERROR: Could not open input device" << std::endl;
    return EXIT_FAILURE;
  }

  FunKeyMonkeyModule module(options["p"].as<std::string>());

  if(!module.ready())
  {
    std::cerr << "ERROR: Could not open plugin" << std::endl;
    return EXIT_FAILURE;
  }

  if(options.count("g") && !evdev.grab(true))
  {
    std::cerr << "ERROR: Could not grab input device" << std::endl;
    return EXIT_FAILURE;
  }

  struct sigaction action;
  memset(&action, 0, sizeof(struct sigaction));
  action.sa_handler = term;
  sigaction(SIGINT, &action, NULL);

  module.init();

  while(!done)
  {
    input_event e = evdev.poll();
    if(e.type != 0)
    {
      module.handle(e);<commit_msg>Added daemonize<commit_after>#include "funkeymonkeymodule.h"
#include "evdevdevice.h"
#include "funkeymonkeymoduleloader.h"
#include "cxxopts.hpp"

#include <iostream>
#include <cstdlib>

#include <memory.h>
#include <signal.h>

volatile sig_atomic_t done = 0;

void term(int)
{
  done = 1;
}

int main(int argc, char** argv)
{
  cxxopts::Options options(argv[0], " - A evdev/uinput wrangler");
  options.add_options()
    ("i,device", "Input device to read from, eg. /dev/input/event0",
     cxxopts::value<std::string>(), "PATH")
    ("p,plugin", "Path to plugin", cxxopts::value<std::string>(), "PATH")
    ("g,grab", "Grab the input device, preventing others from accessing it")
    ("d,daemonize", "Daemonize process")
    ("h,help", "Print help");

  if(argc == 1)
  {
    std::cout << options.help({"", "Group"}) << std::endl;
    return EXIT_SUCCESS;
  }

  try
  {
    options.parse(argc, argv);
  }
  catch(cxxopts::OptionException e)
  {
    std::cerr << "ERROR: parsing options failed: " << e.what() << std::endl;
    return EXIT_FAILURE;
  }

  if(options.count("h"))
  {
    std::cout << options.help({"", "Group"}) << std::endl;
    return EXIT_SUCCESS;
  }

  if(options.count("i") != 1)
  {
    std::cerr << "ERROR: exactly one input device is required" << std::endl;
    return EXIT_FAILURE;
  }

  if(options.count("p") != 1)
  {
    std::cerr << "ERROR: exactly one plugin is required" << std::endl;
    return EXIT_FAILURE;
  }

  EvdevDevice evdev(options["i"].as<std::string>());

  if(!evdev.ready())
  {
    std::cerr << "ERROR: Could not open input device" << std::endl;
    return EXIT_FAILURE;
  }

  FunKeyMonkeyModule module(options["p"].as<std::string>());

  if(!module.ready())
  {
    std::cerr << "ERROR: Could not open plugin" << std::endl;
    return EXIT_FAILURE;
  }

  if(options.count("g") && !evdev.grab(true))
  {
    std::cerr << "ERROR: Could not grab input device" << std::endl;
    return EXIT_FAILURE;
  }

  if(options.count("d") && daemon(1, 0) == -1)
  {
    std::cerr << "ERROR: Could not daemonize, error code " << errno << std::endl;
    return EXIT_FAILURE;
  }

  struct sigaction action;
  memset(&action, 0, sizeof(struct sigaction));
  action.sa_handler = term;
  sigaction(SIGINT, &action, NULL);

  module.init();

  while(!done)
  {
    input_event e = evdev.poll();
    if(e.type != 0)
    {
      module.handle(e);
{'fraction_non_alphanumeric': 0.18463908450704225, 'fraction_numerical': 0.0046214788732394365, 'mean_word_length': 3.6952479338842976, 'pattern_counts': {'":': 0, '<': 93, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7606887', 'n_tokens_mistral': 1715, 'n_tokens_neox': 1676, 'n_words': 367}