1 /*
2 * context.c - context save and restore
3 *
4 * This file is part of zsh, the Z shell.
5 *
6 * Copyright (c) 2015 Peter Stephenson
7 * All rights reserved.
8 *
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
14 *
15 * In no event shall Peter Stephenson or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Peter Stephenson and the Zsh Development Group have been advised of
19 * the possibility of such damage.
20 *
21 * Peter Stephenson and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose. The software
24 * provided hereunder is on an "as is" basis, and Peter Stephenson and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
27 *
28 */
29 /*
30 * This short file provides a home for the stack of saved contexts.
31 * The actions for saving and restoring are encapsulated within
32 * individual modules.
33 */
34
35 #include "zsh.mdh"
36 #include "context.pro"
37
38 struct context_stack {
39 struct context_stack *next;
40
41 struct hist_stack hist_stack;
42 struct lex_stack lex_stack;
43 struct parse_stack parse_stack;
44 };
45
46 static struct context_stack *cstack;
47
48 /* save some or all of current context */
49
50 /**/
51 mod_export void
zcontext_save_partial(int parts)52 zcontext_save_partial(int parts)
53 {
54 struct context_stack *cs;
55
56 queue_signals();
57
58 cs = (struct context_stack *)malloc(sizeof(struct context_stack));
59
60 if (parts & ZCONTEXT_HIST) {
61 hist_context_save(&cs->hist_stack, !cstack);
62 }
63 if (parts & ZCONTEXT_LEX) {
64 lex_context_save(&cs->lex_stack, !cstack);
65 }
66 if (parts & ZCONTEXT_PARSE) {
67 parse_context_save(&cs->parse_stack, !cstack);
68 }
69
70 cs->next = cstack;
71 cstack = cs;
72
73 unqueue_signals();
74 }
75
76 /* save context in full */
77
78 /**/
79 mod_export void
zcontext_save(void)80 zcontext_save(void)
81 {
82 zcontext_save_partial(ZCONTEXT_HIST|ZCONTEXT_LEX|ZCONTEXT_PARSE);
83 }
84
85 /* restore context or part thereof */
86
87 /**/
88 mod_export void
zcontext_restore_partial(int parts)89 zcontext_restore_partial(int parts)
90 {
91 struct context_stack *cs = cstack;
92
93 DPUTS(!cstack, "BUG: zcontext_restore() without zcontext_save()");
94
95 queue_signals();
96 cstack = cstack->next;
97
98 if (parts & ZCONTEXT_HIST) {
99 hist_context_restore(&cs->hist_stack, !cstack);
100 }
101 if (parts & ZCONTEXT_LEX) {
102 lex_context_restore(&cs->lex_stack, !cstack);
103 }
104 if (parts & ZCONTEXT_PARSE) {
105 parse_context_restore(&cs->parse_stack, !cstack);
106 }
107
108 free(cs);
109
110 unqueue_signals();
111 }
112
113 /* restore full context */
114
115 /**/
116 mod_export void
zcontext_restore(void)117 zcontext_restore(void)
118 {
119 zcontext_restore_partial(ZCONTEXT_HIST|ZCONTEXT_LEX|ZCONTEXT_PARSE);
120 }
121