13ff48bf5SDavid du Colombier /* Copyright (C) 1991, 1995, 1998, 1999 artofcode LLC. All rights reserved. 27dd7cddfSDavid du Colombier 3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or 4*593dc095SDavid du Colombier implied. 57dd7cddfSDavid du Colombier 6*593dc095SDavid du Colombier This software is distributed under license and may not be copied, 7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms 8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution. 97dd7cddfSDavid du Colombier 10*593dc095SDavid du Colombier For more information about licensing, please refer to 11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on 12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or 13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110, 14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861. 157dd7cddfSDavid du Colombier */ 167dd7cddfSDavid du Colombier 17*593dc095SDavid du Colombier /* $Id: opdef.h,v 1.6 2002/06/16 04:47:10 lpd Exp $ */ 187dd7cddfSDavid du Colombier /* Operator definition interface for Ghostscript */ 197dd7cddfSDavid du Colombier 207dd7cddfSDavid du Colombier #ifndef opdef_INCLUDED 217dd7cddfSDavid du Colombier # define opdef_INCLUDED 227dd7cddfSDavid du Colombier 237dd7cddfSDavid du Colombier /* 247dd7cddfSDavid du Colombier * Define the structure for initializing the operator table. Each operator 257dd7cddfSDavid du Colombier * file zxxx.c declares an array of these as follows: 267dd7cddfSDavid du Colombier 277dd7cddfSDavid du Colombier const op_def * const zxxx_op_defs[] = { 287dd7cddfSDavid du Colombier {"1name", zname}, 297dd7cddfSDavid du Colombier ... 307dd7cddfSDavid du Colombier op_def_end(iproc) 317dd7cddfSDavid du Colombier }; 327dd7cddfSDavid du Colombier 333ff48bf5SDavid du Colombier * where iproc is an initialization procedure for the file or 0, and, for 343ff48bf5SDavid du Colombier * each operator defined, the initial digit of the name string indicates 353ff48bf5SDavid du Colombier * the number of arguments and zname is the address of the associated C 363ff48bf5SDavid du Colombier * function to invoke. 373ff48bf5SDavid du Colombier * 383ff48bf5SDavid du Colombier * The array definition always appears at the END of the file, to avoid 393ff48bf5SDavid du Colombier * the need for forward declarations for all the operator procedures. 403ff48bf5SDavid du Colombier * 417dd7cddfSDavid du Colombier * Operators may be stored in dictionaries other than systemdict. 427dd7cddfSDavid du Colombier * We support this with op_def entries of a special form: 437dd7cddfSDavid du Colombier 447dd7cddfSDavid du Colombier op_def_begin_dict("dictname"), 457dd7cddfSDavid du Colombier 467dd7cddfSDavid du Colombier */ 477dd7cddfSDavid du Colombier typedef struct { 487dd7cddfSDavid du Colombier const char *oname; 497dd7cddfSDavid du Colombier op_proc_t proc; 507dd7cddfSDavid du Colombier } op_def; 517dd7cddfSDavid du Colombier 527dd7cddfSDavid du Colombier #define op_def_begin_dict(dname) {dname, 0} 537dd7cddfSDavid du Colombier #define op_def_begin_filter() op_def_begin_dict("filterdict") 547dd7cddfSDavid du Colombier #define op_def_begin_level2() op_def_begin_dict("level2dict") 557dd7cddfSDavid du Colombier #define op_def_begin_ll3() op_def_begin_dict("ll3dict") 567dd7cddfSDavid du Colombier #define op_def_is_begin_dict(def) ((def)->proc == 0) 577dd7cddfSDavid du Colombier #define op_def_end(iproc) {0, iproc} 587dd7cddfSDavid du Colombier 597dd7cddfSDavid du Colombier /* 607dd7cddfSDavid du Colombier * NOTE: for implementation reasons, a single table of operator definitions 617dd7cddfSDavid du Colombier * is limited to 16 entries, including op_def_begin_xxx entries. If a file 627dd7cddfSDavid du Colombier * defines more operators than this, it must split them into multiple 637dd7cddfSDavid du Colombier * tables and have multiple -oper entries in the makefile. Currently, 647dd7cddfSDavid du Colombier * only 4 out of 85 operator files require this. 657dd7cddfSDavid du Colombier */ 667dd7cddfSDavid du Colombier #define OP_DEFS_LOG2_MAX_SIZE 4 677dd7cddfSDavid du Colombier #define OP_DEFS_MAX_SIZE (1 << OP_DEFS_LOG2_MAX_SIZE) 687dd7cddfSDavid du Colombier 697dd7cddfSDavid du Colombier /* 707dd7cddfSDavid du Colombier * Define the table of pointers to all operator definition tables. 717dd7cddfSDavid du Colombier */ 727dd7cddfSDavid du Colombier extern const op_def *const op_defs_all[]; 737dd7cddfSDavid du Colombier 747dd7cddfSDavid du Colombier /* 757dd7cddfSDavid du Colombier * Internal operators whose names begin with %, such as continuation 767dd7cddfSDavid du Colombier * operators, do not appear in systemdict. Ghostscript assumes 777dd7cddfSDavid du Colombier * that these operators cannot appear anywhere (in executable form) 787dd7cddfSDavid du Colombier * except on the e-stack; to maintain this invariant, the execstack 797dd7cddfSDavid du Colombier * operator converts them to literal form, and cvx refuses to convert 807dd7cddfSDavid du Colombier * them back. As a result of this invariant, they do not need to 817dd7cddfSDavid du Colombier * push themselves back on the e-stack when executed, since the only 827dd7cddfSDavid du Colombier * place they could have come from was the e-stack. 837dd7cddfSDavid du Colombier */ 847dd7cddfSDavid du Colombier #define op_def_is_internal(def) ((def)->oname[1] == '%') 857dd7cddfSDavid du Colombier 867dd7cddfSDavid du Colombier /* 877dd7cddfSDavid du Colombier * All operators are catalogued in a table; this is necessary because 887dd7cddfSDavid du Colombier * they must have a short packed representation for the sake of 'bind'. 897dd7cddfSDavid du Colombier * The `size' of an operator is normally its index in this table; 907dd7cddfSDavid du Colombier * however, internal operators have a `size' of 0, and their true index 917dd7cddfSDavid du Colombier * must be found by searching the table for their procedure address. 927dd7cddfSDavid du Colombier */ 93*593dc095SDavid du Colombier ushort op_find_index(const ref *); 947dd7cddfSDavid du Colombier 957dd7cddfSDavid du Colombier #define op_index(opref)\ 967dd7cddfSDavid du Colombier (r_size(opref) == 0 ? op_find_index(opref) : r_size(opref)) 977dd7cddfSDavid du Colombier 987dd7cddfSDavid du Colombier /* 997dd7cddfSDavid du Colombier * There are actually two kinds of operators: the real ones (t_operator), 1007dd7cddfSDavid du Colombier * and ones defined by procedures (t_oparray). The catalog for t_operators 1017dd7cddfSDavid du Colombier * is (indirectly) op_defs_all, and their index is in the range 1027dd7cddfSDavid du Colombier * [1..op_def_count-1]. 1037dd7cddfSDavid du Colombier */ 1047dd7cddfSDavid du Colombier #define op_index_is_operator(index) ((index) < op_def_count) 1057dd7cddfSDavid du Colombier extern const uint op_def_count; 1067dd7cddfSDavid du Colombier 1077dd7cddfSDavid du Colombier #define op_index_def(index)\ 1087dd7cddfSDavid du Colombier (&op_defs_all[(index) >> OP_DEFS_LOG2_MAX_SIZE]\ 1097dd7cddfSDavid du Colombier [(index) & (OP_DEFS_MAX_SIZE - 1)]) 1107dd7cddfSDavid du Colombier #define op_num_args(opref) (op_index_def(op_index(opref))->oname[0] - '0') 1117dd7cddfSDavid du Colombier #define op_index_proc(index) (op_index_def(index)->proc) 1127dd7cddfSDavid du Colombier 1137dd7cddfSDavid du Colombier /* 1147dd7cddfSDavid du Colombier * There are two catalogs for t_oparrays, one global and one local. 1157dd7cddfSDavid du Colombier * Operator indices for the global table are in the range 1167dd7cddfSDavid du Colombier * [op_def_count..op_def_count+op_array_global.count-1] 1177dd7cddfSDavid du Colombier * Operator indices for the local table are in the range 1187dd7cddfSDavid du Colombier * [op_def_count+r_size(&op_array_global.table).. 1197dd7cddfSDavid du Colombier * op_def_count+r_size(&op_array_global.table)+op_array_local.count-1] 1207dd7cddfSDavid du Colombier */ 1217dd7cddfSDavid du Colombier typedef struct op_array_table_s { 1227dd7cddfSDavid du Colombier ref table; /* t_array */ 1237dd7cddfSDavid du Colombier ushort *nx_table; /* name indices */ 1247dd7cddfSDavid du Colombier uint count; /* # of occupied entries */ 1257dd7cddfSDavid du Colombier uint base_index; /* operator index of first entry */ 1267dd7cddfSDavid du Colombier uint attrs; /* ref attrs of ops in this table */ 1277dd7cddfSDavid du Colombier ref *root_p; /* self-pointer for GC root */ 1287dd7cddfSDavid du Colombier } op_array_table; 1297dd7cddfSDavid du Colombier extern op_array_table 1307dd7cddfSDavid du Colombier op_array_table_global, op_array_table_local; 1317dd7cddfSDavid du Colombier 1327dd7cddfSDavid du Colombier #define op_index_op_array_table(index)\ 1337dd7cddfSDavid du Colombier ((index) < op_array_table_local.base_index ?\ 1347dd7cddfSDavid du Colombier &op_array_table_global : &op_array_table_local) 1357dd7cddfSDavid du Colombier 1367dd7cddfSDavid du Colombier /* 1377dd7cddfSDavid du Colombier * Convert an operator index to an operator or oparray ref. 1387dd7cddfSDavid du Colombier * This is only used for debugging and for 'get' from packed arrays, 1397dd7cddfSDavid du Colombier * so it doesn't have to be very fast. 1407dd7cddfSDavid du Colombier */ 141*593dc095SDavid du Colombier void op_index_ref(uint, ref *); 1427dd7cddfSDavid du Colombier 1437dd7cddfSDavid du Colombier #endif /* opdef_INCLUDED */ 144