1 /*-------------------------------------------------------------------------
2 * A stack of automaton states to handle nested conditionals.
4 * Copyright (c) 2000-2024, 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
));
27 * Destroy all the elements from the stack. The stack itself is not freed.
30 conditional_stack_reset(ConditionalStack cstack
)
33 return; /* nothing to do here */
35 while (conditional_stack_pop(cstack
))
43 conditional_stack_destroy(ConditionalStack cstack
)
45 conditional_stack_reset(cstack
);
50 * Create a new conditional branch.
53 conditional_stack_push(ConditionalStack cstack
, ifState new_state
)
55 IfStackElem
*p
= (IfStackElem
*) pg_malloc(sizeof(IfStackElem
));
57 p
->if_state
= new_state
;
60 p
->next
= cstack
->head
;
65 * Destroy the topmost conditional branch.
66 * Returns false if there was no branch to end.
69 conditional_stack_pop(ConditionalStack cstack
)
71 IfStackElem
*p
= cstack
->head
;
75 cstack
->head
= cstack
->head
->next
;
81 * Returns current stack depth, for debugging purposes.
84 conditional_stack_depth(ConditionalStack cstack
)
90 IfStackElem
*p
= cstack
->head
;
103 * Fetch the current state of the top of the stack.
106 conditional_stack_peek(ConditionalStack cstack
)
108 if (conditional_stack_empty(cstack
))
110 return cstack
->head
->if_state
;
114 * Change the state of the topmost branch.
115 * Returns false if there was no branch state to set.
118 conditional_stack_poke(ConditionalStack cstack
, ifState new_state
)
120 if (conditional_stack_empty(cstack
))
122 cstack
->head
->if_state
= new_state
;
127 * True if there are no active \if-blocks.
130 conditional_stack_empty(ConditionalStack cstack
)
132 return cstack
->head
== NULL
;
136 * True if we should execute commands normally; that is, the current
137 * conditional branch is active, or there is no open \if block.
140 conditional_active(ConditionalStack cstack
)
142 ifState s
= conditional_stack_peek(cstack
);
144 return s
== IFSTATE_NONE
|| s
== IFSTATE_TRUE
|| s
== IFSTATE_ELSE_TRUE
;
148 * Save current query buffer length in topmost stack entry.
151 conditional_stack_set_query_len(ConditionalStack cstack
, int len
)
153 Assert(!conditional_stack_empty(cstack
));
154 cstack
->head
->query_len
= len
;
158 * Fetch last-recorded query buffer length from topmost stack entry.
159 * Will return -1 if no stack or it was never saved.
162 conditional_stack_get_query_len(ConditionalStack cstack
)
164 if (conditional_stack_empty(cstack
))
166 return cstack
->head
->query_len
;
170 * Save current parenthesis nesting depth in topmost stack entry.
173 conditional_stack_set_paren_depth(ConditionalStack cstack
, int depth
)
175 Assert(!conditional_stack_empty(cstack
));
176 cstack
->head
->paren_depth
= depth
;
180 * Fetch last-recorded parenthesis nesting depth from topmost stack entry.
181 * Will return -1 if no stack or it was never saved.
184 conditional_stack_get_paren_depth(ConditionalStack cstack
)
186 if (conditional_stack_empty(cstack
))
188 return cstack
->head
->paren_depth
;