<commit_before>#ifndef EVENTBACKEND_H
#define EVENTBACKEND_H

// POSIX
#include <poll.h>
#include <sys/types.h>

// STL
#include <unordered_map>

// PDTK
#include <cxxutils/posix_helpers.h>



enum class EventFlags : uint32_t
{
  Invalid       = 0x00000000,
  Error         = 0x00000001, // FD encountered an error (output only)
  Disconnected  = 0x00000002, // FD has disconnected (output only)
  Readable      = 0x00000004, // FD has content to read
  Writeable     = 0x00000008, // FD is writeable
  EdgeTrigger   = 0x00000010, // FD will be edge-triggered (input only)
  ReadEvent     = 0x00000020, // File/directory was read from
  WriteEvent    = 0x00000040, // File/directory was written to
  AttributeMod  = 0x00000080, // File/directory metadata was modified
  Moved         = 0x00000100, // File/directory was moved
  Deleted       = 0x00000200, // File/directory was deleted
  Created       = 0x00000400, // File/directory was created
  ExecEvent     = 0x00000800, // Process called exec*()
  ExitEvent     = 0x00001000, // Process exited
  ForkEvent     = 0x00002000, // Process forked
  UIDEvent      = 0x00004000, // Process changed its User ID
  GIDEvent      = 0x00008000, // Process changed its Group ID
  SIDEvent      = 0x00010000, // Process changed its Session ID

  Any           = 0xFFFFFFFF, // any flag
};
static_assert(sizeof(EventFlags) == sizeof(uint32_t), "EventFlags: bad size");

constexpr uint32_t operator | (EventFlags a, EventFlags b) { return static_cast<uint32_t>(a) | static_cast<uint32_t>(b); }

struct EventFlags_t
{
  // FD events
  uint32_t Error        : 1;
  uint32_t Disconnected : 1;
  uint32_t Readable     : 1;
  uint32_t Writeable    : 1;
  uint32_t EdgeTrigger  : 1;
  // FS events
  uint32_t ReadEvent    : 1;
  uint32_t WriteEvent   : 1;
  uint32_t AttributeMod : 1;
  uint32_t Moved        : 1;
  uint32_t Deleted      : 1;
  uint32_t Created      : 1;
  // Proc events
  uint32_t ExecEvent    : 1;
  uint32_t ExitEvent    : 1;
  uint32_t ForkEvent    : 1;
  uint32_t UIDEvent     : 1;
  uint32_t GIDEvent     : 1;
  uint32_t SIDEvent     : 1;

  EventFlags_t(uint32_t flags) : EventFlags_t(static_cast<EventFlags>(flags)) { }
  EventFlags_t(EventFlags flags = EventFlags::Invalid) noexcept { *reinterpret_cast<EventFlags*>(this) = flags; }
  operator EventFlags(void) const noexcept { return *reinterpret_cast<const EventFlags*>(this); }

  void unset(EventFlags flags) noexcept { return unset(static_cast<uint32_t>(flags)); }
  void unset(uint32_t flags) noexcept { *reinterpret_cast<uint32_t*>(this) &= *reinterpret_cast<uint32_t*>(this) ^flags; }
  bool isSet(EventFlags flags) const noexcept { return isSet(static_cast<uint32_t>(flags)); }
  bool isSet(uint32_t flags) const noexcept { return *reinterpret_cast<const uint32_t*>(this) & flags; }

  bool operator >= (EventFlags a) const noexcept { return *reinterpret_cast<const uint32_t*>(this) >= static_cast<uint32_t>(a); }
};
static_assert(sizeof(EventFlags_t) == sizeof(EventFlags), "EventFlags_t: bad size");

struct EventData_t
{
  EventFlags_t flags;
  pid_t pid;  // process id
  pid_t tgid; // thread group id
  union
  {
    struct
    {
      uint32_t event_op1;
      uint32_t event_op2;
    };

    struct
    {
      uint32_t exit_code;
      uint32_t exit_signal;
    };

    struct
    {
      pid_t child_pid;
      pid_t child_tgid;
    };

    struct
    {
      uint32_t gid;
      uint32_t egid;
    };

    struct
    {
      uint32_t uid;
      uint32_t euid;
    };
  };

  EventData_t(EventFlags_t _flags = EventFlags::Invalid, uint32_t _pid = 0, uint32_t _tgid = 0, uint32_t op1 = 0, uint32_t op2 = 0)
    : flags(_flags), pid(_pid), tgid(_tgid), event_op1(op1), event_op2(op2) { }
};

struct EventBackend // TODO: convert to namespace
{
  static void init(void) noexcept;
  static void destroy(void) noexcept;

  static posix::fd_t watch(const char* path, EventFlags_t flags = EventFlags::Readable) noexcept; // add file events to montior
  static posix::fd_t watch(int target, EventFlags_t flags = EventFlags::Readable) noexcept; // add FD or process events to montior

  static bool remove(int target, EventFlags_t flags = EventFlags::Readable) noexcept; // remove from watch queue

  static bool getevents(int timeout = -1) noexcept;

  static std::unordered_multimap<posix::fd_t, EventFlags_t> queue; // watch queue
  static std::unordered_multimap<posix::fd_t, EventData_t> results; // results from getevents()

  static struct platform_dependant* platform;
};

#endif // EVENTBACKEND_H<commit_msg>add/use better flags<commit_after>#ifndef EVENTBACKEND_H
#define EVENTBACKEND_H

// POSIX
#include <poll.h>
#include <sys/types.h>

// STL
#include <unordered_map>

// PDTK
#include <cxxutils/posix_helpers.h>


enum class EventFlags : uint32_t
{
  Invalid       = 0x00000000,
  Error         = 0x00000001, // FD encountered an error (output only)
  Disconnected  = 0x00000002, // FD has disconnected (output only)
  Readable      = 0x00000004, // FD has content to read
  Writeable     = 0x00000008, // FD is writeable
  EdgeTrigger   = 0x00000010, // FD will be edge-triggered (input only)
  ReadEvent     = 0x00000020, // File/directory was read from
  WriteEvent    = 0x00000040, // File/directory was written to
  AttributeMod  = 0x00000080, // File/directory metadata was modified
  Moved         = 0x00000100, // File/directory was moved
  Deleted       = 0x00000200, // File/directory was deleted
  Created       = 0x00000400, // File/directory was created
  FileEvent     = 0x000007E0, // Any file/directory event
  ExecEvent     = 0x00000800, // Process called exec*()
  ExitEvent     = 0x00001000, // Process exited
  ForkEvent     = 0x00002000, // Process forked
  UIDEvent      = 0x00004000, // Process changed its User ID
  GIDEvent      = 0x00008000, // Process changed its Group ID
  SIDEvent      = 0x00010000, // Process changed its Session ID
  ProcEvent     = 0x0001F800, // Any process event

  Any           = 0xFFFFFFFF, // any flag
};
static_assert(sizeof(EventFlags) == sizeof(uint32_t), "EventFlags: bad size");

constexpr uint32_t operator | (EventFlags a, EventFlags b) { return static_cast<uint32_t>(a) | static_cast<uint32_t>(b); }

struct EventFlags_t
{
  // FD events
  uint32_t Error        : 1;
  uint32_t Disconnected : 1;
  uint32_t Readable     : 1;
  uint32_t Writeable    : 1;
  uint32_t EdgeTrigger  : 1;
  // FS events
  uint32_t ReadEvent    : 1;
  uint32_t WriteEvent   : 1;
  uint32_t AttributeMod : 1;
  uint32_t Moved        : 1;
  uint32_t Deleted      : 1;
  uint32_t Created      : 1;
  // Proc events
  uint32_t ExecEvent    : 1;
  uint32_t ExitEvent    : 1;
  uint32_t ForkEvent    : 1;
  uint32_t UIDEvent     : 1;
  uint32_t GIDEvent     : 1;
  uint32_t SIDEvent     : 1;

  EventFlags_t(uint32_t flags) : EventFlags_t(static_cast<EventFlags>(flags)) { }
  EventFlags_t(EventFlags flags = EventFlags::Invalid) noexcept { *reinterpret_cast<EventFlags*>(this) = flags; }
  operator EventFlags(void) const noexcept { return *reinterpret_cast<const EventFlags*>(this); }

  void unset(EventFlags flags) noexcept { return unset(static_cast<uint32_t>(flags)); }
  void unset(uint32_t flags) noexcept { *reinterpret_cast<uint32_t*>(this) &= *reinterpret_cast<uint32_t*>(this) ^flags; }
  bool isSet(EventFlags flags) const noexcept { return isSet(static_cast<uint32_t>(flags)); }
  bool isSet(uint32_t flags) const noexcept { return *reinterpret_cast<const uint32_t*>(this) & flags; }

  bool operator >= (EventFlags a) const noexcept { return *reinterpret_cast<const uint32_t*>(this) >= static_cast<uint32_t>(a); }
};
static_assert(sizeof(EventFlags_t) == sizeof(EventFlags), "EventFlags_t: bad size");

struct EventData_t
{
  EventFlags_t flags;
  pid_t pid;  // process id
  pid_t tgid; // thread group id
  union
  {
    struct
    {
      uint32_t event_op1;
      uint32_t event_op2;
    };

    struct
    {
      uint32_t exit_code;
      uint32_t exit_signal;
    };

    struct
    {
      pid_t child_pid;
      pid_t child_tgid;
    };

    struct
    {
      uint32_t gid;
      uint32_t egid;
    };

    struct
    {
      uint32_t uid;
      uint32_t euid;
    };
  };

  EventData_t(EventFlags_t _flags = EventFlags::Invalid, uint32_t _pid = 0, uint32_t _tgid = 0, uint32_t op1 = 0, uint32_t op2 = 0)
    : flags(_flags), pid(_pid), tgid(_tgid), event_op1(op1), event_op2(op2) { }
};

struct EventBackend // TODO: convert to namespace
{
  static void init(void) noexcept;
  static void destroy(void) noexcept;

  static posix::fd_t watch(const char* path, EventFlags_t flags = EventFlags::FileEvent) noexcept; // add file events to montior
  static posix::fd_t watch(int target, EventFlags_t flags = EventFlags::Readable) noexcept; // add FD or process events to montior

  static bool remove(int target, EventFlags_t flags = EventFlags::Readable) noexcept; // remove from watch queue

  static bool getevents(int timeout = -1) noexcept;

  static std::unordered_multimap<posix::fd_t, EventFlags_t> queue; // watch queue
  static std::unordered_multimap<posix::fd_t, EventData_t> results; // results from getevents()

  static struct platform_dependant* platform;
};

#endif // EVENTBACKEND_H
{'fraction_non_alphanumeric': 0.10139251523063533, 'fraction_numerical': 0.06288076588337685, 'mean_word_length': 3.373453853472883, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 12, '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': '1974592', 'n_tokens_mistral': 3577, 'n_tokens_neox': 3111, 'n_words': 811}