
#ifndef ETHERCAT_SUGAR_CLEANUP_H
#define ETHERCAT_SUGAR_CLEANUP_H

#include "../ethercat_types.h"
#include "../master/core.h"
#include <stdint.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif

#if defined(__GNUC__) || defined(__clang__)
#  define EC_HAS_CLEANUP_ATTR 1
#else
#  define EC_HAS_CLEANUP_ATTR 0
#endif

#if EC_HAS_CLEANUP_ATTR

static inline void _ec_auto_dispose(uint16_t* p) {
    if (p && *p) {
        Dispose(*p);
        *p = 0;
    }
}

static inline void _ec_auto_stop_dispose(uint16_t* p) {
    if (p && *p) {
        Stop(*p);
        Dispose(*p);
        *p = 0;
    }
}

static inline void _ec_auto_free(void* pp) {
    void** p = (void**)pp;
    if (p && *p) {
        free(*p);
        *p = NULL;
    }
}

static inline void _ec_auto_free_sdk(void* pp) {
    void** p = (void**)pp;
    if (p && *p) {
        FreeMemory(*p);
        *p = NULL;
    }
}

#define EC_AUTO_DISPOSE       __attribute__((cleanup(_ec_auto_dispose)))

#define EC_AUTO_STOP_DISPOSE  __attribute__((cleanup(_ec_auto_stop_dispose)))

#define EC_AUTO_FREE          __attribute__((cleanup(_ec_auto_free)))

#define EC_AUTO_FREE_SDK      __attribute__((cleanup(_ec_auto_free_sdk)))

#else

#define EC_AUTO_DISPOSE
#define EC_AUTO_STOP_DISPOSE
#define EC_AUTO_FREE
#define EC_AUTO_FREE_SDK

#endif

#ifdef __cplusplus
}
#endif

#endif
