1 /*-------------------------------------------------------------------------
2 * A stack of automaton states to handle nested conditionals.
4 * Copyright (c) 2000-2021, PostgreSQL Global Development Group
6 * src/fe_utils/conditional.c
8 *-------------------------------------------------------------------------
10 #include "postgres_fe.h"
12 #include "fe_utils/conditional.h"
18 conditional_stack_create(void)
20 ConditionalStack cstack
= pg_malloc(sizeof(ConditionalStackData
));
30 conditional_stack_destroy(ConditionalStack cstack
)
32 while (conditional_stack_pop(cstack
))
38 * Create a new conditional branch.
41 conditional_stack_push(ConditionalStack cstack
, ifState new_state
)
43 IfStackElem
*p
= (IfStackElem
*) pg_malloc(sizeof(IfStackElem
));
45 p
->if_state
= new_state
;
48 p
->next
= cstack
->head
;
53 * Destroy the topmost conditional branch.
54 * Returns false if there was no branch to end.
57 conditional_stack_pop(ConditionalStack cstack
)
59 IfStackElem
*p
= cstack
->head
;
63 cstack
->head
= cstack
->head
->next
;
69 * Returns current stack depth, for debugging purposes.
72 conditional_stack_depth(ConditionalStack cstack
)
78 IfStackElem
*p
= cstack
->head
;
91 * Fetch the current state of the top of the stack.
94 conditional_stack_peek(ConditionalStack cstack
)
96 if (conditional_stack_empty(cstack
))
98 return cstack
->head
->if_state
;
102 * Change the state of the topmost branch.
103 * Returns false if there was no branch state to set.
106 conditional_stack_poke(ConditionalStack cstack
, ifState new_state
)
108 if (conditional_stack_empty(cstack
))
110 cstack
->head
->if_state
= new_state
;
115 * True if there are no active \if-blocks.
118 conditional_stack_empty(ConditionalStack cstack
)
120 return cstack
->head
== NULL
;
124 * True if we should execute commands normally; that is, the current
125 * conditional branch is active, or there is no open \if block.
128 conditional_active(ConditionalStack cstack
)
130 ifState s
= conditional_stack_peek(cstack
);
132 return s
== IFSTATE_NONE
|| s
== IFSTATE_TRUE
|| s
== IFSTATE_ELSE_TRUE
;
136 * Save current query buffer length in topmost stack entry.
139 conditional_stack_set_query_len(ConditionalStack cstack
, int len
)
141 Assert(!conditional_stack_empty(cstack
));
142 cstack
->head
->query_len
= len
;
146 * Fetch last-recorded query buffer length from topmost stack entry.
147 * Will return -1 if no stack or it was never saved.
150 conditional_stack_get_query_len(ConditionalStack cstack
)
152 if (conditional_stack_empty(cstack
))
154 return cstack
->head
->query_len
;
158 * Save current parenthesis nesting depth in topmost stack entry.
161 conditional_stack_set_paren_depth(ConditionalStack cstack
, int depth
)
163 Assert(!conditional_stack_empty(cstack
));
164 cstack
->head
->paren_depth
= depth
;
168 * Fetch last-recorded parenthesis nesting depth from topmost stack entry.
169 * Will return -1 if no stack or it was never saved.
172 conditional_stack_get_paren_depth(ConditionalStack cstack
)
174 if (conditional_stack_empty(cstack
))
176 return cstack
->head
->paren_depth
;