]> git.ipfire.org Git - thirdparty/cups.git/blob - pstoraster/estack.h
Import cups.org releases
[thirdparty/cups.git] / pstoraster / estack.h
1 /* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved.
2
3 This file is part of GNU Ghostscript.
4
5 GNU Ghostscript is distributed in the hope that it will be useful, but
6 WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
7 to anyone for the consequences of using it or for whether it serves any
8 particular purpose or works at all, unless he says so in writing. Refer
9 to the GNU General Public License for full details.
10
11 Everyone is granted permission to copy, modify and redistribute GNU
12 Ghostscript, but only under the conditions described in the GNU General
13 Public License. A copy of this license is supposed to have been given
14 to you along with GNU Ghostscript so you can know your rights and
15 responsibilities. It should be in a file named COPYING. Among other
16 things, the copyright notice and this notice must be preserved on all
17 copies.
18
19 Aladdin Enterprises supports the work of the GNU Project, but is not
20 affiliated with the Free Software Foundation or the GNU Project. GNU
21 Ghostscript, as distributed by Aladdin Enterprises, does not require any
22 GNU software to build or run it.
23 */
24
25 /*$Id$ */
26 /* Definitions for the execution stack */
27
28 #ifndef estack_INCLUDED
29 # define estack_INCLUDED
30
31 #include "iestack.h"
32
33 /* There's only one exec stack right now.... */
34 #define esfile (iexec_stack.current_file)
35 #define esfile_clear_cache() (esfile = 0)
36 #define esfile_set_cache(pref) (esfile = (pref))
37 #define esfile_check_cache()\
38 if ( r_has_type_attrs(esp, t_file, a_executable) )\
39 esfile_set_cache(esp)
40
41 /* Define the execution stack pointers. */
42 extern exec_stack_t iexec_stack;
43
44 #define e_stack (iexec_stack.stack)
45 #define esbot (e_stack.bot)
46 #define esp (e_stack.p)
47 #define estop (e_stack.top)
48
49 /*
50 * The execution stack is used for three purposes:
51 *
52 * - Procedures being executed are held here. They always have
53 * type = t_array, t_mixedarray, or t_shortarray, with a_executable set.
54 * More specifically, the e-stack holds the as yet unexecuted tail of the
55 * procedure.
56 *
57 * - if, ifelse, etc. push arguments to be executed here.
58 * They may be any kind of object whatever.
59 *
60 * - Control operators (filenameforall, for, repeat, loop, forall,
61 * pathforall, run, stopped, ...) mark the stack by pushing whatever state
62 * they need to save or keep track of and then an object with type = t_null,
63 * attrs = a_executable, size = es_xxx (see below), and value.opproc = a
64 * cleanup procedure that will get called whenever the execution stack is
65 * about to get cut back beyond this point because of an error, stop, exit,
66 * or quit. (Executable null objects can't ever appear on the e-stack
67 * otherwise: if a control operator pushes one, it gets popped immediately.)
68 * The cleanup procedure is called with esp pointing just BELOW the mark,
69 * i.e., the mark has already been popped.
70 *
71 * The loop operators also push whatever state they need,
72 * followed by an operator object that handles continuing the loop.
73 *
74 * Note that there are many internal operators that need to be handled like
75 * looping operators -- for example, all the 'show' operators, since they
76 * may call out to BuildChar procedures.
77 */
78
79 /* Macro for marking the execution stack */
80 #define make_mark_estack(ep, es_idx, proc)\
81 make_tasv(ep, t_null, a_executable, es_idx, opproc, proc)
82 #define push_mark_estack(es_idx, proc)\
83 (++esp, make_mark_estack(esp, es_idx, proc))
84 #define r_is_estack_mark(ep)\
85 r_has_type_attrs(ep, t_null, a_executable)
86 #define estack_mark_index(ep) r_size(ep)
87 #define set_estack_mark_index(ep, es_idx) r_set_size(ep, es_idx)
88
89 /* Macro for pushing an operator on the execution stack */
90 /* to represent a continuation procedure */
91 #define make_op_estack(ep, proc)\
92 make_oper(ep, 0, proc)
93 #define push_op_estack(proc)\
94 (++esp, make_op_estack(esp, proc))
95
96 /* Macro to ensure enough room on the execution stack */
97 #define check_estack(n)\
98 if ( esp > estop - (n) )\
99 { int es_code_ = ref_stack_extend(&e_stack, n);\
100 if ( es_code_ < 0 ) return es_code_;\
101 }
102
103 /* Macro to ensure enough entries on the execution stack */
104 #define check_esp(n)\
105 if ( esp < esbot + ((n) - 1) )\
106 { e_stack.requested = (n); return_error(e_ExecStackUnderflow); }
107
108 /* Define the various kinds of execution stack marks. */
109 #define es_other 0 /* internal use */
110 #define es_show 1 /* show operators */
111 #define es_for 2 /* iteration operators */
112 #define es_stopped 3 /* stopped operator */
113
114 /*
115 * Pop a given number of elements off the execution stack,
116 * executing cleanup procedures as necessary.
117 */
118 void pop_estack(P1(uint));
119
120 /*
121 * The execution stack is implemented as a linked list of blocks;
122 * operators that can push or pop an unbounded number of values, or that
123 * access the entire e-stack, must take this into account. These are:
124 * exit .stop .instopped countexecstack execstack currentfile
125 * .execn
126 * pop_estack(exit, stop, error recovery)
127 * gs_show_find(all the show operators)
128 * In addition, for e-stack entries created by control operators, we must
129 * ensure that the mark and its data are never separated. We do this
130 * by ensuring that when splitting the top block, at least N items
131 * are kept in the new top block above the bottommost retained mark,
132 * where N is the largest number of data items associated with a mark.
133 * Finally, in order to avoid specific checks for underflowing a block,
134 * we put a guard entry at the bottom of each block except the top one
135 * that contains a procedure that returns an internal "exec stack block
136 * underflow" error.
137 */
138
139 #endif /* estack_INCLUDED */