2) {
 *       if (GetSlaveGroup(mi, si) == 2) WriteSlaveOutputByte(mi, si, 0, 0xFF);
 *   }
 *
 *
 *   EC_FOREACH_OP_SLAVE(mi, si) {
 *
 *   }
 *
 * 注: 这些宏在 C99 模式下可编译, for 内部声明 idx 变量需要 C99+ (-std=c99 或更高)
 *
 * Copyright (c) Hangzhou Darra Technology Co., Ltd.
 */

#ifndef ETHERCAT_SUGAR_FOREACH_H
#define ETHERCAT_SUGAR_FOREACH_H

#include "../ethercat_types.h"
#include "../master/core.h"
#include "../slave/core.h"
#include "../master/diagnostics.h"
#include <stdint.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

#ifndef EC_SUGAR_INLINE
#  if defined(_MSC_VER)
#    define EC_SUGAR_INLINE static __inline
#  else
#    define EC_SUGAR_INLINE static inline
#  endif
#endif

EC_SUGAR_INLINE uint16_t ec_foreach_slave_count_(uint16_t mi) {
    const void* st = GetMasterState(mi);
    if (st == NULL) return 0;

    return (uint16_t)(*(const int32_t*)((const uint8_t*)st + 4));
}

#define EC_FOREACH_SLAVE(master_index, idx_var)                          \
    for (uint16_t idx_var = 1,                                           \
                  _ec_n_##idx_var = ec_foreach_slave_count_(master_index); \
         idx_var <= _ec_n_##idx_var;                                     \
         ++idx_var)

#define EC_FOREACH_SLAVE_IN_GROUP(master_index, idx_var, group)          \
    EC_FOREACH_SLAVE(master_index, idx_var)                              \
        if (GetSlaveGroup((master_index), idx_var) != (group)) {} else

#define EC_FOREACH_OP_SLAVE(master_index, idx_var)                       \
    EC_FOREACH_SLAVE(master_index, idx_var)                              \
        if (GetSlaveState((master_index), idx_var) !=                    \
            (uint8_t)EC_STATE_OPERATIONAL) {} else

#define EC_FOREACH_ROOT(roots_array, root_count, idx_var)                \
    for (int idx_var = 0; idx_var < (int)(root_count); ++idx_var)

#define EC_FOREACH_CHILD(child_array, child_count, idx_var)              \
    for (int idx_var = 0; idx_var < (int)(child_count); ++idx_var)

#ifdef __cplusplus
}
#endif

#endif
