[PATCH] Screen buffers ESC keypresses indefinitely since sgr support
[screen.git] / src / winmsgcond.c
blobfcebb200ad75f551ce7d6485baa1b827eee38bce
1 /* Copyright (c) 2013
2 * Mike Gerwitz (mtg@gnu.org)
4 * This file is part of GNU screen.
6 * GNU screen is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file COPYING); if not, see
18 * <https://www.gnu.org/licenses>.
20 ****************************************************************
23 #include "config.h"
25 #include "winmsgcond.h"
27 #include <assert.h>
28 #include <stdlib.h>
31 /* Initialize new condition and set to false; can be used to re-initialize a
32 * condition for re-use */
33 void wmc_init(WinMsgCond *cond, int offset)
35 cond->locked = false;
36 cond->offset = offset;
37 cond->initialized = true;
38 wmc_clear(cond);
41 /* Mark condition as true */
42 void wmc_set(WinMsgCond *cond)
44 if (cond->locked)
45 return;
47 cond->state = true;
50 /* Clear condition (equivalent to non-match) */
51 void wmc_clear(WinMsgCond *cond)
53 if (cond->locked)
54 return;
56 cond->state = false;
59 /* Determine if condition is active (has been initialized and can be used) */
60 bool wmc_is_active(const WinMsgCond *cond)
62 return cond->initialized;
65 /* Determine if a condition is true; the result is undefined if
66 * !wmc_active(cond) */
67 bool wmc_is_set(const WinMsgCond *cond)
69 return cond->state;
72 /* "else" encounted */
73 int wmc_else(WinMsgCond *cond, int offset, bool *changed)
75 assert(wmc_is_active(cond));
77 /* if we're already set, then there is no point in processing the "else";
78 * we will therefore consider the previous condition to have succeeded, so
79 * now keep track of the start of the else so that it may be clobbered
80 * instead of the beginning of the true condition---that is, we're accepting
81 * the destination string up until this point */
82 if (wmc_is_set(cond)) {
83 wmc_init(cond, offset); /* track this as a new condition */
84 cond->locked = true; /* "else" shall never succeed at this point */
86 /* we want to keep the string we have so far (the truth string) */
87 if (changed)
88 *changed = false;
89 return offset;
92 /* now that we have reached "else" and are not true, we can never be true;
93 * discard the truth part of the string */
94 int prevoffset = cond->offset;
95 cond->offset = offset;
97 /* the "else" part must always be true at this point, because the previous
98 * condition failed */
99 wmc_set(cond);
100 cond->locked = true;
102 if (changed)
103 *changed = true;
104 return prevoffset;
107 /* End condition and determine if string should be reset or kept---if our value
108 * is truthful, then accept the string, otherwise reject and reset to the
109 * position that we were initialized with */
110 int wmc_end(const WinMsgCond *cond, int offset, bool *changed)
112 bool set = wmc_is_set(cond);
113 if (changed)
114 *changed = !set;
116 return (set) ? offset : cond->offset;
119 /* Deactivate a condition, preventing its use; this allows a single allocation
120 * to be re-used and ignored until activated */
121 void wmc_deinit(WinMsgCond *cond)
123 cond->state = false;
124 cond->offset = 0;
125 cond->locked = true;
126 cond->initialized = false;