1 /*
2 * $Id: fltstack.h,v 1.19 2018/10/27 11:16:47 tom Exp $
3 * A simple stack for lex states
4 */
5
6 #ifndef FLTSTACK_H
7 #define FLTSTACK_H 1
8 /*
9 * Redefine since filters.h uses BEGIN(), which confuses our notion of current
10 * state.
11 */
12 #undef BeginQuote
13 #define BeginQuote(state, attr) \
14 new_state(state); \
15 flt_bfr_begin(attr); \
16 flt_bfr_append(yytext, yyleng)
17
18 #undef FinishQuote
19 #define FinishQuote(state) \
20 flt_bfr_append(yytext, yyleng);\
21 flt_bfr_finish();\
22 new_state(state)
23
24 typedef struct {
25 int state;
26 #ifdef FLTSTACK_EXTRA
27 FLTSTACK_EXTRA
28 #endif
29 } STACK;
30 static STACK *stk_state = 0;
31 static int cur_state;
32
33 static int stk_limit = 0;
34 static int stk_level = -1;
35
36 #define FLTSTACK_OK (stk_level >= 0 && stk_level < stk_limit)
37 #define FLTSTACK_THIS stk_state[stk_level]
38 #define FLT_STATE FLTSTACK_THIS.state
39
40 static void new_state(int);
41 static void push_state(int);
42 static void begin_state(int);
43 static void end_state(void);
44
45 #ifndef UNUSED_POP_STATE
46 static void pop_state(void);
47 #endif
48
49 #else
50
51 /*
52 * Record the given state at the current stack level, and tell lex about it.
53 */
54 static void
new_state(int code)55 new_state(int code)
56 {
57 FLEX_PRINTF((stderr, "new_state(%d)\n", code));
58 if (FLTSTACK_OK && stk_state != 0)
59 FLT_STATE = code;
60 BEGIN(code);
61 cur_state = code; /* antique lex's have no valid YYSTATE */
62 }
63
64 #ifndef UNUSED_POP_STATE
65 static void
pop_state(void)66 pop_state(void)
67 {
68 #ifdef INITIAL
69 int state = INITIAL;
70 #else
71 int state = 0; /* cater to broken "new" flex */
72 #endif
73 FLEX_PRINTF((stderr, "pop_state() level %d\n", stk_level));
74 --stk_level;
75 if (FLTSTACK_OK)
76 state = FLT_STATE;
77 new_state(state);
78 }
79 #endif
80
81 static void
push_state(int state)82 push_state(int state)
83 {
84 ++stk_level;
85 FLEX_PRINTF((stderr, "push_state(%d) level %d\n", state, stk_level));
86 if ((stk_level >= stk_limit) || (stk_state == 0)) {
87 size_t have = sizeof(STACK) * (unsigned) stk_limit;
88 size_t want = sizeof(STACK) * (unsigned) (stk_limit += (20 + stk_level));
89 stk_state = type_alloc(STACK, (void *) stk_state, want, &have);
90 }
91 #ifdef FLTSTACK_EXTRA_PUSH
92 if (FLTSTACK_OK) {
93 FLTSTACK_EXTRA_PUSH
94 }
95 #endif
96 new_state(state);
97 }
98
99 /*
100 * Call this from do_filter(), to set the initial state and store that value
101 * on the stack.
102 */
103 static void
begin_state(int code)104 begin_state(int code)
105 {
106 FLEX_PRINTF((stderr, "begin_state(%d)\n", code));
107 stk_level = -1;
108 push_state(code);
109 }
110
111 /*
112 * Cleanup
113 */
114 static void
end_state(void)115 end_state(void)
116 {
117 #if NO_LEAKS
118 if (stk_state != 0) {
119 free(stk_state);
120 stk_state = 0;
121 }
122 #endif
123 }
124 #endif /* FLTSTACK_H */
125