#ifndef __PSIGNAL_H__
#define __PSIGNAL_H__ 1

// Signal handling part of i77 perms.

// Setting this up so that *all* IMP %signal calls map to linux signal SUGUSR1
// Any other Linux signals (such as generated by say divide-by-zero) will need
// to be trapped and converted into an IMP signal.

#include <signal.h>
#include <setjmp.h>

#include "imptypes.h"

typedef struct _imp_eventfm _imp_eventfm;
typedef struct _imp_eventfm {
  // These are values used in Imp77 signal mechanism, not relevant to C:
  int EVENT;
  union {
    int SUB;
    int SUBEVENT;
  };
  union {
    int INFO;
    int EXTRA;
  };
  // char *MESSAGE;
  _imp_string MESSAGE;

  _imp_string FILE;
  int LINE;
  // these are for the C signal mechanism:
  sigjmp_buf env;
  _imp_eventfm *prev;
} _imp_eventfm;

extern _imp_eventfm _imp_event;
extern sig_atomic_t _imp_last_signal;

static inline _imp_eventfm _imp_EVENT(void) { return _imp_event; }
static inline int _imp_EVENTNO(void) { return _imp_event.EVENT; }
static inline int _imp_SUBEVENT(void) { return _imp_event.SUB/*EVENT*/; }
static inline int _imp_EVENTINFO(void) { return _imp_event.INFO/*EXTRA*/; }
static inline _imp_string _imp_EVENTMESSAGE(void) {
  //if (_imp_event.MESSAGE == 0/*NULL*/) return _imp_str_literal("");
  return _imp_event.MESSAGE;
}

static inline int _imp_EVENTLINE(void) { return _imp_event.LINE; }

static inline _imp_string _imp_EVENTFILE(void) {
  //if (_imp_event.FILE == 0/*NULL*/) return _imp_str_literal("");
  return _imp_event.FILE;
}


extern void _imp_signal_handler(int sig);
extern _imp_eventfm *_imp_on_event_enter(_imp_eventfm *f);
extern void _imp_on_event_leave(_imp_eventfm *f);

extern void _signal_event(_imp_string file,
                          int line,
                          _imp_string message,
                          int event, int subevent, int extra);

// (Use our internal file/line value if available)
#define _imp_signal(A,B,C,D)                                       \
             _signal_event(_imp_current_file                       \
                             ? _imp_c2istr(_imp_current_file)      \
                             : _imp_str_literal(__FILE__),         \
                             _imp_current_line                     \
                               ? _imp_current_line                 \
                               : __LINE__, _imp_c2istr(D), A,B,C)

#define _imp_on_event(...) (0)    // TO DO!!!!

#endif // defined __PSIGNAL_H__
