unlang_t *found;
} unlang_frame_state_redundant_t;
-typedef enum {
- UNWIND_FLAG_NONE = 0x00, //!< No flags.
- UNWIND_FLAG_REPEAT = 0x01, //!< Repeat the frame on the way up the stack.
- UNWIND_FLAG_TOP_FRAME = 0x02, //!< are we the top frame of the stack?
+#define UNWIND_FLAG_NONE 0x00 //!< No flags.
+#define UNWIND_FLAG_REPEAT 0x01 //!< Repeat the frame on the way up the stack.
+#define UNWIND_FLAG_TOP_FRAME 0x02 //!< are we the top frame of the stack?
///< If true, causes the interpreter to stop
///< interpreting and return, control then passes
///< to whatever called the interpreter.
- UNWIND_FLAG_BREAK_POINT = 0x04, //!< 'break' stops here.
- UNWIND_FLAG_RETURN_POINT = 0x08, //!< 'return' stops here.
- UNWIND_FLAG_NO_CLEAR = 0x10, //!< Keep unwinding, don't clear the unwind flag.
- UNWIND_FLAG_MAX = 0xff
-} unlang_unwind_flags_t;
+#define UNWIND_FLAG_BREAK_POINT 0x04 //!< 'break' stops here.
+#define UNWIND_FLAG_RETURN_POINT 0x08 //!< 'return' stops here.
+#define UNWIND_FLAG_NO_CLEAR 0x10 //!< Keep unwinding, don't clear the unwind flag.
+
#define repeatable_set(_frame) ((_frame)->uflags |= UNWIND_FLAG_REPEAT)
#define top_frame_set(_frame) ((_frame)->uflags |= UNWIND_FLAG_TOP_FRAME)
#define break_point_set(_frame) ((_frame)->uflags |= UNWIND_FLAG_BREAK_POINT)
#define return_point_set(_frame) ((_frame)->uflags |= UNWIND_FLAG_RETURN_POINT)
-/*
- * clang doesn't like the fact that the masks
- * are outside the range of values the enum
- * can represent *sigh*
- */
-#define repeatable_clear(_frame) ((_frame)->uflags) -= (((_frame)->uflags) & UNWIND_FLAG_REPEAT)
-#define top_frame_clear(_frame) ((_frame)->uflags) -= (((_frame)->uflags) & UNWIND_FLAG_TOP_FRAME)
-#define break_point_clear(_frame) ((_frame)->uflags) -= (((_frame)->uflags) & UNWIND_FLAG_BREAK_POINT)
-#define return_point_clear(_frame) ((_frame)->uflags) -= (((_frame)->uflags) & UNWIND_FLAG_RETURN_POINT)
+#define repeatable_clear(_frame) ((_frame)->uflags) &= ~UNWIND_FLAG_REPEAT
+#define top_frame_clear(_frame) ((_frame)->uflags) &= ~UNWIND_FLAG_TOP_FRAME
+#define break_point_clear(_frame) ((_frame)->uflags) &= ~UNWIND_FLAG_BREAK_POINT
+#define return_point_clear(_frame) ((_frame)->uflags) &= ~UNWIND_FLAG_RETURN_POINT
#define is_repeatable(_frame) ((_frame)->uflags & UNWIND_FLAG_REPEAT)
#define is_top_frame(_frame) ((_frame)->uflags & UNWIND_FLAG_TOP_FRAME)
#define is_break_point(_frame) ((_frame)->uflags & UNWIND_FLAG_BREAK_POINT)
#define is_return_point(_frame) ((_frame)->uflags & UNWIND_FLAG_RETURN_POINT)
+#define UNWIND_TO_BREAK(_stack) ((_stack)->unwind = (UNWIND_FLAG_BREAK_POINT | UNWIND_FLAG_TOP_FRAME))
+#define UNWIND_TO_RETURN(_stack) ((_stack)->unwind = (UNWIND_FLAG_RETURN_POINT | UNWIND_FLAG_TOP_FRAME))
+#define UNWIND_ALL(_stack) ((_stack)->unwind = (UNWIND_FLAG_TOP_FRAME | UNWIND_FLAG_NO_CLEAR))
+
/** Our interpreter stack, as distinct from the C stack
*
* We don't call the modules recursively. Instead we iterate over a list of #unlang_t and
///< frame lower in the stack to determine if the
///< result stored in the lower stack frame should
///< be replaced.
- unlang_unwind_flags_t uflags; //!< Unwind markers
+ uint8_t uflags; //!< Unwind markers
} unlang_stack_frame_t;
/** An unlang stack associated with a request
typedef struct {
rlm_rcode_t result; //!< The current stack rcode.
int depth; //!< Current depth we're executing at.
- unlang_unwind_flags_t unwind; //!< Unwind to this frame if it exists.
+ uint8_t unwind; //!< Unwind to this frame if it exists.
///< This is used for break and return.
unlang_stack_frame_t frame[UNLANG_STACK_MAX]; //!< The stack...
} unlang_stack_t;