2 |
- |
1 |
/* Copyright (C) 1991, 1995, 1998, 1999 artofcode LLC. All rights reserved.
|
|
|
2 |
|
|
|
3 |
This software is provided AS-IS with no warranty, either express or
|
|
|
4 |
implied.
|
|
|
5 |
|
|
|
6 |
This software is distributed under license and may not be copied,
|
|
|
7 |
modified or distributed except as expressly authorized under the terms
|
|
|
8 |
of the license contained in the file LICENSE in this distribution.
|
|
|
9 |
|
|
|
10 |
For more information about licensing, please refer to
|
|
|
11 |
http://www.ghostscript.com/licensing/. For information on
|
|
|
12 |
commercial licensing, go to http://www.artifex.com/licensing/ or
|
|
|
13 |
contact Artifex Software, Inc., 101 Lucas Valley Road #110,
|
|
|
14 |
San Rafael, CA 94903, U.S.A., +1(415)492-9861.
|
|
|
15 |
*/
|
|
|
16 |
|
|
|
17 |
/* $Id: opdef.h,v 1.6 2002/06/16 04:47:10 lpd Exp $ */
|
|
|
18 |
/* Operator definition interface for Ghostscript */
|
|
|
19 |
|
|
|
20 |
#ifndef opdef_INCLUDED
|
|
|
21 |
# define opdef_INCLUDED
|
|
|
22 |
|
|
|
23 |
/*
|
|
|
24 |
* Define the structure for initializing the operator table. Each operator
|
|
|
25 |
* file zxxx.c declares an array of these as follows:
|
|
|
26 |
|
|
|
27 |
const op_def * const zxxx_op_defs[] = {
|
|
|
28 |
{"1name", zname},
|
|
|
29 |
...
|
|
|
30 |
op_def_end(iproc)
|
|
|
31 |
};
|
|
|
32 |
|
|
|
33 |
* where iproc is an initialization procedure for the file or 0, and, for
|
|
|
34 |
* each operator defined, the initial digit of the name string indicates
|
|
|
35 |
* the number of arguments and zname is the address of the associated C
|
|
|
36 |
* function to invoke.
|
|
|
37 |
*
|
|
|
38 |
* The array definition always appears at the END of the file, to avoid
|
|
|
39 |
* the need for forward declarations for all the operator procedures.
|
|
|
40 |
*
|
|
|
41 |
* Operators may be stored in dictionaries other than systemdict.
|
|
|
42 |
* We support this with op_def entries of a special form:
|
|
|
43 |
|
|
|
44 |
op_def_begin_dict("dictname"),
|
|
|
45 |
|
|
|
46 |
*/
|
|
|
47 |
typedef struct {
|
|
|
48 |
const char *oname;
|
|
|
49 |
op_proc_t proc;
|
|
|
50 |
} op_def;
|
|
|
51 |
|
|
|
52 |
#define op_def_begin_dict(dname) {dname, 0}
|
|
|
53 |
#define op_def_begin_filter() op_def_begin_dict("filterdict")
|
|
|
54 |
#define op_def_begin_level2() op_def_begin_dict("level2dict")
|
|
|
55 |
#define op_def_begin_ll3() op_def_begin_dict("ll3dict")
|
|
|
56 |
#define op_def_is_begin_dict(def) ((def)->proc == 0)
|
|
|
57 |
#define op_def_end(iproc) {0, iproc}
|
|
|
58 |
|
|
|
59 |
/*
|
|
|
60 |
* NOTE: for implementation reasons, a single table of operator definitions
|
|
|
61 |
* is limited to 16 entries, including op_def_begin_xxx entries. If a file
|
|
|
62 |
* defines more operators than this, it must split them into multiple
|
|
|
63 |
* tables and have multiple -oper entries in the makefile. Currently,
|
|
|
64 |
* only 4 out of 85 operator files require this.
|
|
|
65 |
*/
|
|
|
66 |
#define OP_DEFS_LOG2_MAX_SIZE 4
|
|
|
67 |
#define OP_DEFS_MAX_SIZE (1 << OP_DEFS_LOG2_MAX_SIZE)
|
|
|
68 |
|
|
|
69 |
/*
|
|
|
70 |
* Define the table of pointers to all operator definition tables.
|
|
|
71 |
*/
|
|
|
72 |
extern const op_def *const op_defs_all[];
|
|
|
73 |
|
|
|
74 |
/*
|
|
|
75 |
* Internal operators whose names begin with %, such as continuation
|
|
|
76 |
* operators, do not appear in systemdict. Ghostscript assumes
|
|
|
77 |
* that these operators cannot appear anywhere (in executable form)
|
|
|
78 |
* except on the e-stack; to maintain this invariant, the execstack
|
|
|
79 |
* operator converts them to literal form, and cvx refuses to convert
|
|
|
80 |
* them back. As a result of this invariant, they do not need to
|
|
|
81 |
* push themselves back on the e-stack when executed, since the only
|
|
|
82 |
* place they could have come from was the e-stack.
|
|
|
83 |
*/
|
|
|
84 |
#define op_def_is_internal(def) ((def)->oname[1] == '%')
|
|
|
85 |
|
|
|
86 |
/*
|
|
|
87 |
* All operators are catalogued in a table; this is necessary because
|
|
|
88 |
* they must have a short packed representation for the sake of 'bind'.
|
|
|
89 |
* The `size' of an operator is normally its index in this table;
|
|
|
90 |
* however, internal operators have a `size' of 0, and their true index
|
|
|
91 |
* must be found by searching the table for their procedure address.
|
|
|
92 |
*/
|
|
|
93 |
ushort op_find_index(const ref *);
|
|
|
94 |
|
|
|
95 |
#define op_index(opref)\
|
|
|
96 |
(r_size(opref) == 0 ? op_find_index(opref) : r_size(opref))
|
|
|
97 |
|
|
|
98 |
/*
|
|
|
99 |
* There are actually two kinds of operators: the real ones (t_operator),
|
|
|
100 |
* and ones defined by procedures (t_oparray). The catalog for t_operators
|
|
|
101 |
* is (indirectly) op_defs_all, and their index is in the range
|
|
|
102 |
* [1..op_def_count-1].
|
|
|
103 |
*/
|
|
|
104 |
#define op_index_is_operator(index) ((index) < op_def_count)
|
|
|
105 |
extern const uint op_def_count;
|
|
|
106 |
|
|
|
107 |
#define op_index_def(index)\
|
|
|
108 |
(&op_defs_all[(index) >> OP_DEFS_LOG2_MAX_SIZE]\
|
|
|
109 |
[(index) & (OP_DEFS_MAX_SIZE - 1)])
|
|
|
110 |
#define op_num_args(opref) (op_index_def(op_index(opref))->oname[0] - '0')
|
|
|
111 |
#define op_index_proc(index) (op_index_def(index)->proc)
|
|
|
112 |
|
|
|
113 |
/*
|
|
|
114 |
* There are two catalogs for t_oparrays, one global and one local.
|
|
|
115 |
* Operator indices for the global table are in the range
|
|
|
116 |
* [op_def_count..op_def_count+op_array_global.count-1]
|
|
|
117 |
* Operator indices for the local table are in the range
|
|
|
118 |
* [op_def_count+r_size(&op_array_global.table)..
|
|
|
119 |
* op_def_count+r_size(&op_array_global.table)+op_array_local.count-1]
|
|
|
120 |
*/
|
|
|
121 |
typedef struct op_array_table_s {
|
|
|
122 |
ref table; /* t_array */
|
|
|
123 |
ushort *nx_table; /* name indices */
|
|
|
124 |
uint count; /* # of occupied entries */
|
|
|
125 |
uint base_index; /* operator index of first entry */
|
|
|
126 |
uint attrs; /* ref attrs of ops in this table */
|
|
|
127 |
ref *root_p; /* self-pointer for GC root */
|
|
|
128 |
} op_array_table;
|
|
|
129 |
extern op_array_table
|
|
|
130 |
op_array_table_global, op_array_table_local;
|
|
|
131 |
|
|
|
132 |
#define op_index_op_array_table(index)\
|
|
|
133 |
((index) < op_array_table_local.base_index ?\
|
|
|
134 |
&op_array_table_global : &op_array_table_local)
|
|
|
135 |
|
|
|
136 |
/*
|
|
|
137 |
* Convert an operator index to an operator or oparray ref.
|
|
|
138 |
* This is only used for debugging and for 'get' from packed arrays,
|
|
|
139 |
* so it doesn't have to be very fast.
|
|
|
140 |
*/
|
|
|
141 |
void op_index_ref(uint, ref *);
|
|
|
142 |
|
|
|
143 |
#endif /* opdef_INCLUDED */
|