/*
 * ProviewR   Open Source Process Control.
 * Copyright (C) 2005-2025 SSAB EMEA AB.
 *
 * This file is part of ProviewR.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with ProviewR. If not, see <http://www.gnu.org/licenses/>
 *
 * Linking ProviewR statically or dynamically with other modules is
 * making a combined work based on ProviewR. Thus, the terms and
 * conditions of the GNU General Public License cover the whole
 * combination.
 *
 * In addition, as a special exception, the copyright holders of
 * ProviewR give you permission to, from the build function in the
 * ProviewR Configurator, combine ProviewR with modules generated by the
 * ProviewR PLC Editor to a PLC program, regardless of the license
 * terms of these modules. You may copy and distribute the resulting
 * combined work under the terms of your choice, provided that every
 * copy of the combined work is accompanied by a complete copy of
 * the source code of ProviewR (the version used to produce the
 * combined work), being distributed under the terms of the GNU
 * General Public License plus this exception.
 */
/*		 PREPROCESSOR ROUTINES FOR LOGIC CONTROL	    */

And


#define and_exec(obj, expr) obj->Status = (expr);

Or


#define or_exec(obj, expr) obj->Status = (expr);

XOr


#define xor_exec(obj, in1, in2) obj->Status = !((in1) == (in2));

Edge


#define edge_exec(obj, in)                                                     \
  obj->Status = (in && !obj->StatusOld);                                       \
  obj->StatusOld = in;

AArithm


#define aarithm_exec(obj, expr) obj->ActVal = expr;

DArithm


#define darithm_exec(obj, expr) obj->Status = expr;

CArithm


#define carithm_exec(obj, expr)                                                \
  {                                                                            \
    expr                                                                       \
  }

SR_S


#define sr_s_exec(obj, set, reset)                                             \
  if (set)                                                                     \
    obj->Status = true;                                                        \
  else if (reset)                                                              \
    obj->Status = false;

SR_R


#define sr_r_exec(obj, set, reset)                                             \
  if (reset)                                                                   \
    obj->Status = false;                                                       \
  else if (set)                                                                \
    obj->Status = true;

Inv


#define inv_exec(obj, in) obj->Status = !in;

Pulse


#define pulse_exec(obj, in)                                                    \
  timer2_scan(tp, obj);                                                        \
  if (in && !obj->StatusOld) {                                                 \
    timer2_in(tp, obj);                                                        \
    obj->Status = true;                                                        \
  } else                                                                       \
    obj->Status = obj->TimerFlag;                                              \
  obj->StatusOld = in;

Wait


#define wait_exec(obj, in)                                                     \
  timer2_scan(tp, obj);                                                        \
  if (in && !obj->StatusOld) {                                                 \
    timer2_in(tp, obj);                                                        \
  }                                                                            \
  obj->StatusOld = in;                                                         \
  obj->Status = in && !obj->TimerFlag;

Timer


#define timer_exec(obj, in)                                                    \
  timer2_scan(tp, obj);                                                        \
  if (!in && obj->StatusOld) {                                                 \
    timer2_in(tp, obj);                                                        \
  }                                                                            \
  obj->StatusOld = in;                                                         \
  obj->Status = in || obj->TimerFlag;

Waith


#define waith_exec(obj, in, hold)                                              \
  timer2_scan(tp, obj);                                                        \
  if (in) {                                                                    \
    if (!obj->StatusOld) {                                                     \
      timer2_in(tp, obj);                                                      \
      obj->CountOld = obj->TimerCount;                                         \
    }                                                                          \
    if (hold) {                                                                \
      obj->TimerCount = obj->CountOld;                                         \
      obj->StatusOld = true;                                                   \
    } else {                                                                   \
      obj->CountOld = obj->TimerCount;                                         \
      obj->StatusOld = true;                                                   \
      obj->Status = !obj->TimerFlag;                                           \
    }                                                                          \
  } else {                                                                     \
    obj->StatusOld = false;                                                    \
    obj->Status = false;                                                       \
  }

SuppressSup


#define SuppressSup_exec(obj, sup, cid, in)                                    \
  switch (cid) {                                                               \
  case pwr_cClass_DSup:                                                        \
    ((pwr_sClass_DSup*)sup)->Suppressed = in;                                  \
    obj->Out = in || ((pwr_sClass_DSup*)sup)->Action;                          \
    break;                                                                     \
  case pwr_cClass_DSupComp:                                                    \
    ((pwr_sClass_DSupComp*)sup)->Suppressed = in;                              \
    obj->Out = in || ((pwr_sClass_DSupComp*)sup)->Action;                      \
    break;                                                                     \
  case pwr_cClass_ASup:                                                        \
    ((pwr_sClass_ASup*)sup)->Suppressed = in;                                  \
    obj->Out = in || ((pwr_sClass_ASup*)sup)->Action;                          \
    break;                                                                     \
  case pwr_cClass_ASupComp:                                                    \
    ((pwr_sClass_ASupComp*)sup)->Suppressed = in;                              \
    obj->Out = in || ((pwr_sClass_ASupComp*)sup)->Action;                      \
    break;                                                                     \
  default:;                                                                    \
  }                                                                            \
  obj->Suppressed = in;