xref: /plan9/sys/src/cmd/gs/src/zmisc.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier /* Copyright (C) 1989, 1995, 1997, 1999 Aladdin Enterprises.  All rights reserved.
2*7dd7cddfSDavid du Colombier 
3*7dd7cddfSDavid du Colombier    This file is part of Aladdin Ghostscript.
4*7dd7cddfSDavid du Colombier 
5*7dd7cddfSDavid du Colombier    Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author
6*7dd7cddfSDavid du Colombier    or distributor accepts any responsibility for the consequences of using it,
7*7dd7cddfSDavid du Colombier    or for whether it serves any particular purpose or works at all, unless he
8*7dd7cddfSDavid du Colombier    or she says so in writing.  Refer to the Aladdin Ghostscript Free Public
9*7dd7cddfSDavid du Colombier    License (the "License") for full details.
10*7dd7cddfSDavid du Colombier 
11*7dd7cddfSDavid du Colombier    Every copy of Aladdin Ghostscript must include a copy of the License,
12*7dd7cddfSDavid du Colombier    normally in a plain ASCII text file named PUBLIC.  The License grants you
13*7dd7cddfSDavid du Colombier    the right to copy, modify and redistribute Aladdin Ghostscript, but only
14*7dd7cddfSDavid du Colombier    under certain conditions described in the License.  Among other things, the
15*7dd7cddfSDavid du Colombier    License requires that the copyright notice and this notice be preserved on
16*7dd7cddfSDavid du Colombier    all copies.
17*7dd7cddfSDavid du Colombier  */
18*7dd7cddfSDavid du Colombier 
19*7dd7cddfSDavid du Colombier /*$Id: zmisc.c,v 1.1 2000/03/09 08:40:45 lpd Exp $ */
20*7dd7cddfSDavid du Colombier /* Miscellaneous operators */
21*7dd7cddfSDavid du Colombier #include "errno_.h"
22*7dd7cddfSDavid du Colombier #include "memory_.h"
23*7dd7cddfSDavid du Colombier #include "string_.h"
24*7dd7cddfSDavid du Colombier #include "ghost.h"
25*7dd7cddfSDavid du Colombier #include "gscdefs.h"		/* for gs_serialnumber */
26*7dd7cddfSDavid du Colombier #include "gp.h"
27*7dd7cddfSDavid du Colombier #include "oper.h"
28*7dd7cddfSDavid du Colombier #include "ialloc.h"
29*7dd7cddfSDavid du Colombier #include "idict.h"
30*7dd7cddfSDavid du Colombier #include "dstack.h"		/* for name lookup in bind */
31*7dd7cddfSDavid du Colombier #include "iname.h"
32*7dd7cddfSDavid du Colombier #include "ipacked.h"
33*7dd7cddfSDavid du Colombier #include "ivmspace.h"
34*7dd7cddfSDavid du Colombier #include "store.h"
35*7dd7cddfSDavid du Colombier 
36*7dd7cddfSDavid du Colombier /* <proc> bind <proc> */
37*7dd7cddfSDavid du Colombier inline private bool
38*7dd7cddfSDavid du Colombier r_is_ex_oper(const ref *rp)
39*7dd7cddfSDavid du Colombier {
40*7dd7cddfSDavid du Colombier     return (r_has_attr(rp, a_executable) &&
41*7dd7cddfSDavid du Colombier 	    (r_btype(rp) == t_operator || r_type(rp) == t_oparray));
42*7dd7cddfSDavid du Colombier }
43*7dd7cddfSDavid du Colombier private int
44*7dd7cddfSDavid du Colombier zbind(i_ctx_t *i_ctx_p)
45*7dd7cddfSDavid du Colombier {
46*7dd7cddfSDavid du Colombier     os_ptr op = osp;
47*7dd7cddfSDavid du Colombier     uint depth = 1;
48*7dd7cddfSDavid du Colombier     ref defn;
49*7dd7cddfSDavid du Colombier     register os_ptr bsp;
50*7dd7cddfSDavid du Colombier 
51*7dd7cddfSDavid du Colombier     switch (r_type(op)) {
52*7dd7cddfSDavid du Colombier 	case t_array:
53*7dd7cddfSDavid du Colombier 	case t_mixedarray:
54*7dd7cddfSDavid du Colombier 	case t_shortarray:
55*7dd7cddfSDavid du Colombier 	    defn = *op;
56*7dd7cddfSDavid du Colombier 	    break;
57*7dd7cddfSDavid du Colombier 	case t_oparray:
58*7dd7cddfSDavid du Colombier 	    defn = *op->value.const_refs;
59*7dd7cddfSDavid du Colombier 	    break;
60*7dd7cddfSDavid du Colombier 	default:
61*7dd7cddfSDavid du Colombier 	    return_op_typecheck(op);
62*7dd7cddfSDavid du Colombier     }
63*7dd7cddfSDavid du Colombier     push(1);
64*7dd7cddfSDavid du Colombier     *op = defn;
65*7dd7cddfSDavid du Colombier     bsp = op;
66*7dd7cddfSDavid du Colombier     /*
67*7dd7cddfSDavid du Colombier      * We must not make the top-level procedure read-only,
68*7dd7cddfSDavid du Colombier      * but we must bind it even if it is read-only already.
69*7dd7cddfSDavid du Colombier      *
70*7dd7cddfSDavid du Colombier      * Here are the invariants for the following loop:
71*7dd7cddfSDavid du Colombier      *      `depth' elements have been pushed on the ostack;
72*7dd7cddfSDavid du Colombier      *      For i < depth, p = ref_stack_index(&o_stack, i):
73*7dd7cddfSDavid du Colombier      *        *p is an array (or packedarray) ref.
74*7dd7cddfSDavid du Colombier      */
75*7dd7cddfSDavid du Colombier     while (depth) {
76*7dd7cddfSDavid du Colombier 	while (r_size(bsp)) {
77*7dd7cddfSDavid du Colombier 	    ref_packed *const tpp = (ref_packed *)bsp->value.packed; /* break const */
78*7dd7cddfSDavid du Colombier 
79*7dd7cddfSDavid du Colombier 	    r_dec_size(bsp, 1);
80*7dd7cddfSDavid du Colombier 	    if (r_is_packed(tpp)) {
81*7dd7cddfSDavid du Colombier 		/* Check for a packed executable name */
82*7dd7cddfSDavid du Colombier 		ushort elt = *tpp;
83*7dd7cddfSDavid du Colombier 
84*7dd7cddfSDavid du Colombier 		if (r_packed_is_exec_name(&elt)) {
85*7dd7cddfSDavid du Colombier 		    ref nref;
86*7dd7cddfSDavid du Colombier 		    ref *pvalue;
87*7dd7cddfSDavid du Colombier 
88*7dd7cddfSDavid du Colombier 		    name_index_ref(packed_name_index(&elt),
89*7dd7cddfSDavid du Colombier 				   &nref);
90*7dd7cddfSDavid du Colombier 		    if ((pvalue = dict_find_name(&nref)) != 0 &&
91*7dd7cddfSDavid du Colombier 			r_is_ex_oper(pvalue)
92*7dd7cddfSDavid du Colombier 			) {
93*7dd7cddfSDavid du Colombier 			store_check_dest(bsp, pvalue);
94*7dd7cddfSDavid du Colombier 			/*
95*7dd7cddfSDavid du Colombier 			 * Always save the change, since this can only
96*7dd7cddfSDavid du Colombier 			 * happen once.
97*7dd7cddfSDavid du Colombier 			 */
98*7dd7cddfSDavid du Colombier 			ref_do_save(bsp, tpp, "bind");
99*7dd7cddfSDavid du Colombier 			*tpp = pt_tag(pt_executable_operator) +
100*7dd7cddfSDavid du Colombier 			    op_index(pvalue);
101*7dd7cddfSDavid du Colombier 		    }
102*7dd7cddfSDavid du Colombier 		}
103*7dd7cddfSDavid du Colombier 		bsp->value.packed = tpp + 1;
104*7dd7cddfSDavid du Colombier 	    } else {
105*7dd7cddfSDavid du Colombier 		ref *const tp = bsp->value.refs++;
106*7dd7cddfSDavid du Colombier 
107*7dd7cddfSDavid du Colombier 		switch (r_type(tp)) {
108*7dd7cddfSDavid du Colombier 		    case t_name:	/* bind the name if an operator */
109*7dd7cddfSDavid du Colombier 			if (r_has_attr(tp, a_executable)) {
110*7dd7cddfSDavid du Colombier 			    ref *pvalue;
111*7dd7cddfSDavid du Colombier 
112*7dd7cddfSDavid du Colombier 			    if ((pvalue = dict_find_name(tp)) != 0 &&
113*7dd7cddfSDavid du Colombier 				r_is_ex_oper(pvalue)
114*7dd7cddfSDavid du Colombier 				) {
115*7dd7cddfSDavid du Colombier 				store_check_dest(bsp, pvalue);
116*7dd7cddfSDavid du Colombier 				ref_assign_old(bsp, tp, pvalue, "bind");
117*7dd7cddfSDavid du Colombier 			    }
118*7dd7cddfSDavid du Colombier 			}
119*7dd7cddfSDavid du Colombier 			break;
120*7dd7cddfSDavid du Colombier 		    case t_array:	/* push into array if writable */
121*7dd7cddfSDavid du Colombier 			if (!r_has_attr(tp, a_write))
122*7dd7cddfSDavid du Colombier 			    break;
123*7dd7cddfSDavid du Colombier 		    case t_mixedarray:
124*7dd7cddfSDavid du Colombier 		    case t_shortarray:
125*7dd7cddfSDavid du Colombier 			if (r_has_attr(tp, a_executable)) {
126*7dd7cddfSDavid du Colombier 			    /* Make reference read-only */
127*7dd7cddfSDavid du Colombier 			    r_clear_attrs(tp, a_write);
128*7dd7cddfSDavid du Colombier 			    if (bsp >= ostop) {
129*7dd7cddfSDavid du Colombier 				/* Push a new stack block. */
130*7dd7cddfSDavid du Colombier 				ref temp;
131*7dd7cddfSDavid du Colombier 				int code;
132*7dd7cddfSDavid du Colombier 
133*7dd7cddfSDavid du Colombier 				temp = *tp;
134*7dd7cddfSDavid du Colombier 				osp = bsp;
135*7dd7cddfSDavid du Colombier 				code = ref_stack_push(&o_stack, 1);
136*7dd7cddfSDavid du Colombier 				if (code < 0) {
137*7dd7cddfSDavid du Colombier 				    ref_stack_pop(&o_stack, depth);
138*7dd7cddfSDavid du Colombier 				    return_error(code);
139*7dd7cddfSDavid du Colombier 				}
140*7dd7cddfSDavid du Colombier 				bsp = osp;
141*7dd7cddfSDavid du Colombier 				*bsp = temp;
142*7dd7cddfSDavid du Colombier 			    } else
143*7dd7cddfSDavid du Colombier 				*++bsp = *tp;
144*7dd7cddfSDavid du Colombier 			    depth++;
145*7dd7cddfSDavid du Colombier 			}
146*7dd7cddfSDavid du Colombier 		}
147*7dd7cddfSDavid du Colombier 	    }
148*7dd7cddfSDavid du Colombier 	}
149*7dd7cddfSDavid du Colombier 	bsp--;
150*7dd7cddfSDavid du Colombier 	depth--;
151*7dd7cddfSDavid du Colombier 	if (bsp < osbot) {	/* Pop back to the previous stack block. */
152*7dd7cddfSDavid du Colombier 	    osp = bsp;
153*7dd7cddfSDavid du Colombier 	    ref_stack_pop_block(&o_stack);
154*7dd7cddfSDavid du Colombier 	    bsp = osp;
155*7dd7cddfSDavid du Colombier 	}
156*7dd7cddfSDavid du Colombier     }
157*7dd7cddfSDavid du Colombier     osp = bsp;
158*7dd7cddfSDavid du Colombier     return 0;
159*7dd7cddfSDavid du Colombier }
160*7dd7cddfSDavid du Colombier 
161*7dd7cddfSDavid du Colombier /* - serialnumber <int> */
162*7dd7cddfSDavid du Colombier private int
163*7dd7cddfSDavid du Colombier zserialnumber(i_ctx_t *i_ctx_p)
164*7dd7cddfSDavid du Colombier {
165*7dd7cddfSDavid du Colombier     os_ptr op = osp;
166*7dd7cddfSDavid du Colombier 
167*7dd7cddfSDavid du Colombier     push(1);
168*7dd7cddfSDavid du Colombier     make_int(op, gs_serialnumber);
169*7dd7cddfSDavid du Colombier     return 0;
170*7dd7cddfSDavid du Colombier }
171*7dd7cddfSDavid du Colombier 
172*7dd7cddfSDavid du Colombier /* - realtime <int> */
173*7dd7cddfSDavid du Colombier private int
174*7dd7cddfSDavid du Colombier zrealtime(i_ctx_t *i_ctx_p)
175*7dd7cddfSDavid du Colombier {
176*7dd7cddfSDavid du Colombier     os_ptr op = osp;
177*7dd7cddfSDavid du Colombier     long secs_ns[2];
178*7dd7cddfSDavid du Colombier 
179*7dd7cddfSDavid du Colombier     gp_get_realtime(secs_ns);
180*7dd7cddfSDavid du Colombier     push(1);
181*7dd7cddfSDavid du Colombier     make_int(op, secs_ns[0] * 1000 + secs_ns[1] / 1000000);
182*7dd7cddfSDavid du Colombier     return 0;
183*7dd7cddfSDavid du Colombier }
184*7dd7cddfSDavid du Colombier 
185*7dd7cddfSDavid du Colombier /* - usertime <int> */
186*7dd7cddfSDavid du Colombier private int
187*7dd7cddfSDavid du Colombier zusertime(i_ctx_t *i_ctx_p)
188*7dd7cddfSDavid du Colombier {
189*7dd7cddfSDavid du Colombier     os_ptr op = osp;
190*7dd7cddfSDavid du Colombier     long secs_ns[2];
191*7dd7cddfSDavid du Colombier 
192*7dd7cddfSDavid du Colombier     gp_get_usertime(secs_ns);
193*7dd7cddfSDavid du Colombier     push(1);
194*7dd7cddfSDavid du Colombier     make_int(op, secs_ns[0] * 1000 + secs_ns[1] / 1000000);
195*7dd7cddfSDavid du Colombier     return 0;
196*7dd7cddfSDavid du Colombier }
197*7dd7cddfSDavid du Colombier 
198*7dd7cddfSDavid du Colombier /* ---------------- Non-standard operators ---------------- */
199*7dd7cddfSDavid du Colombier 
200*7dd7cddfSDavid du Colombier /* <string> getenv <value_string> true */
201*7dd7cddfSDavid du Colombier /* <string> getenv false */
202*7dd7cddfSDavid du Colombier private int
203*7dd7cddfSDavid du Colombier zgetenv(i_ctx_t *i_ctx_p)
204*7dd7cddfSDavid du Colombier {
205*7dd7cddfSDavid du Colombier     os_ptr op = osp;
206*7dd7cddfSDavid du Colombier     char *str;
207*7dd7cddfSDavid du Colombier     byte *value;
208*7dd7cddfSDavid du Colombier     int len = 0;
209*7dd7cddfSDavid du Colombier 
210*7dd7cddfSDavid du Colombier     check_read_type(*op, t_string);
211*7dd7cddfSDavid du Colombier     str = ref_to_string(op, imemory, "getenv key");
212*7dd7cddfSDavid du Colombier     if (str == 0)
213*7dd7cddfSDavid du Colombier 	return_error(e_VMerror);
214*7dd7cddfSDavid du Colombier     if (gp_getenv(str, (char *)0, &len) > 0) {	/* key missing */
215*7dd7cddfSDavid du Colombier 	ifree_string((byte *) str, r_size(op) + 1, "getenv key");
216*7dd7cddfSDavid du Colombier 	make_false(op);
217*7dd7cddfSDavid du Colombier 	return 0;
218*7dd7cddfSDavid du Colombier     }
219*7dd7cddfSDavid du Colombier     value = ialloc_string(len, "getenv value");
220*7dd7cddfSDavid du Colombier     if (value == 0) {
221*7dd7cddfSDavid du Colombier 	ifree_string((byte *) str, r_size(op) + 1, "getenv key");
222*7dd7cddfSDavid du Colombier 	return_error(e_VMerror);
223*7dd7cddfSDavid du Colombier     }
224*7dd7cddfSDavid du Colombier     DISCARD(gp_getenv(str, (char *)value, &len));	/* can't fail */
225*7dd7cddfSDavid du Colombier     ifree_string((byte *) str, r_size(op) + 1, "getenv key");
226*7dd7cddfSDavid du Colombier     /* Delete the stupid C string terminator. */
227*7dd7cddfSDavid du Colombier     value = iresize_string(value, len, len - 1,
228*7dd7cddfSDavid du Colombier 			   "getenv value");	/* can't fail */
229*7dd7cddfSDavid du Colombier     push(1);
230*7dd7cddfSDavid du Colombier     make_string(op - 1, a_all | icurrent_space, len - 1, value);
231*7dd7cddfSDavid du Colombier     make_true(op);
232*7dd7cddfSDavid du Colombier     return 0;
233*7dd7cddfSDavid du Colombier }
234*7dd7cddfSDavid du Colombier 
235*7dd7cddfSDavid du Colombier /* <name> <proc> .makeoperator <oper> */
236*7dd7cddfSDavid du Colombier private int
237*7dd7cddfSDavid du Colombier zmakeoperator(i_ctx_t *i_ctx_p)
238*7dd7cddfSDavid du Colombier {
239*7dd7cddfSDavid du Colombier     os_ptr op = osp;
240*7dd7cddfSDavid du Colombier     op_array_table *opt;
241*7dd7cddfSDavid du Colombier     uint count;
242*7dd7cddfSDavid du Colombier     ref *tab;
243*7dd7cddfSDavid du Colombier 
244*7dd7cddfSDavid du Colombier     check_type(op[-1], t_name);
245*7dd7cddfSDavid du Colombier     check_proc(*op);
246*7dd7cddfSDavid du Colombier     switch (r_space(op)) {
247*7dd7cddfSDavid du Colombier 	case avm_global:
248*7dd7cddfSDavid du Colombier 	    opt = &op_array_table_global;
249*7dd7cddfSDavid du Colombier 	    break;
250*7dd7cddfSDavid du Colombier 	case avm_local:
251*7dd7cddfSDavid du Colombier 	    opt = &op_array_table_local;
252*7dd7cddfSDavid du Colombier 	    break;
253*7dd7cddfSDavid du Colombier 	default:
254*7dd7cddfSDavid du Colombier 	    return_error(e_invalidaccess);
255*7dd7cddfSDavid du Colombier     }
256*7dd7cddfSDavid du Colombier     count = opt->count;
257*7dd7cddfSDavid du Colombier     tab = opt->table.value.refs;
258*7dd7cddfSDavid du Colombier     /*
259*7dd7cddfSDavid du Colombier      * restore doesn't reset op_array_table.count, but it does
260*7dd7cddfSDavid du Colombier      * remove entries from op_array_table.table.  Since we fill
261*7dd7cddfSDavid du Colombier      * the table in order, we can detect that a restore has occurred
262*7dd7cddfSDavid du Colombier      * by checking whether what should be the most recent entry
263*7dd7cddfSDavid du Colombier      * is occupied.  If not, we scan backwards over the vacated entries
264*7dd7cddfSDavid du Colombier      * to find the true end of the table.
265*7dd7cddfSDavid du Colombier      */
266*7dd7cddfSDavid du Colombier     while (count > 0 && r_has_type(&tab[count - 1], t_null))
267*7dd7cddfSDavid du Colombier 	--count;
268*7dd7cddfSDavid du Colombier     if (count == r_size(&opt->table))
269*7dd7cddfSDavid du Colombier 	return_error(e_limitcheck);
270*7dd7cddfSDavid du Colombier     ref_assign_old(&opt->table, &tab[count], op, "makeoperator");
271*7dd7cddfSDavid du Colombier     opt->nx_table[count] = name_index(op - 1);
272*7dd7cddfSDavid du Colombier     op_index_ref(opt->base_index + count, op - 1);
273*7dd7cddfSDavid du Colombier     opt->count = count + 1;
274*7dd7cddfSDavid du Colombier     pop(1);
275*7dd7cddfSDavid du Colombier     return 0;
276*7dd7cddfSDavid du Colombier }
277*7dd7cddfSDavid du Colombier 
278*7dd7cddfSDavid du Colombier /* - .oserrno <int> */
279*7dd7cddfSDavid du Colombier private int
280*7dd7cddfSDavid du Colombier zoserrno(i_ctx_t *i_ctx_p)
281*7dd7cddfSDavid du Colombier {
282*7dd7cddfSDavid du Colombier     os_ptr op = osp;
283*7dd7cddfSDavid du Colombier 
284*7dd7cddfSDavid du Colombier     push(1);
285*7dd7cddfSDavid du Colombier     make_int(op, errno);
286*7dd7cddfSDavid du Colombier     return 0;
287*7dd7cddfSDavid du Colombier }
288*7dd7cddfSDavid du Colombier 
289*7dd7cddfSDavid du Colombier /* <int> .setoserrno - */
290*7dd7cddfSDavid du Colombier private int
291*7dd7cddfSDavid du Colombier zsetoserrno(i_ctx_t *i_ctx_p)
292*7dd7cddfSDavid du Colombier {
293*7dd7cddfSDavid du Colombier     os_ptr op = osp;
294*7dd7cddfSDavid du Colombier 
295*7dd7cddfSDavid du Colombier     check_type(*op, t_integer);
296*7dd7cddfSDavid du Colombier     errno = op->value.intval;
297*7dd7cddfSDavid du Colombier     pop(1);
298*7dd7cddfSDavid du Colombier     return 0;
299*7dd7cddfSDavid du Colombier }
300*7dd7cddfSDavid du Colombier 
301*7dd7cddfSDavid du Colombier /* <int> .oserrorstring <string> true */
302*7dd7cddfSDavid du Colombier /* <int> .oserrorstring false */
303*7dd7cddfSDavid du Colombier private int
304*7dd7cddfSDavid du Colombier zoserrorstring(i_ctx_t *i_ctx_p)
305*7dd7cddfSDavid du Colombier {
306*7dd7cddfSDavid du Colombier     os_ptr op = osp;
307*7dd7cddfSDavid du Colombier     const char *str;
308*7dd7cddfSDavid du Colombier     int code;
309*7dd7cddfSDavid du Colombier     uint len;
310*7dd7cddfSDavid du Colombier     byte ch;
311*7dd7cddfSDavid du Colombier 
312*7dd7cddfSDavid du Colombier     check_type(*op, t_integer);
313*7dd7cddfSDavid du Colombier     str = gp_strerror((int)op->value.intval);
314*7dd7cddfSDavid du Colombier     if (str == 0 || (len = strlen(str)) == 0) {
315*7dd7cddfSDavid du Colombier 	make_false(op);
316*7dd7cddfSDavid du Colombier 	return 0;
317*7dd7cddfSDavid du Colombier     }
318*7dd7cddfSDavid du Colombier     check_ostack(1);
319*7dd7cddfSDavid du Colombier     code = string_to_ref(str, op, iimemory, ".oserrorstring");
320*7dd7cddfSDavid du Colombier     if (code < 0)
321*7dd7cddfSDavid du Colombier 	return code;
322*7dd7cddfSDavid du Colombier     /* Strip trailing end-of-line characters. */
323*7dd7cddfSDavid du Colombier     while ((len = r_size(op)) != 0 &&
324*7dd7cddfSDavid du Colombier 	   ((ch = op->value.bytes[--len]) == '\r' || ch == '\n')
325*7dd7cddfSDavid du Colombier 	)
326*7dd7cddfSDavid du Colombier 	r_dec_size(op, 1);
327*7dd7cddfSDavid du Colombier     push(1);
328*7dd7cddfSDavid du Colombier     make_true(op);
329*7dd7cddfSDavid du Colombier     return 0;
330*7dd7cddfSDavid du Colombier }
331*7dd7cddfSDavid du Colombier 
332*7dd7cddfSDavid du Colombier /* <string> <bool> .setdebug - */
333*7dd7cddfSDavid du Colombier private int
334*7dd7cddfSDavid du Colombier zsetdebug(i_ctx_t *i_ctx_p)
335*7dd7cddfSDavid du Colombier {
336*7dd7cddfSDavid du Colombier     os_ptr op = osp;
337*7dd7cddfSDavid du Colombier     check_read_type(op[-1], t_string);
338*7dd7cddfSDavid du Colombier     check_type(*op, t_boolean);
339*7dd7cddfSDavid du Colombier     {
340*7dd7cddfSDavid du Colombier 	int i;
341*7dd7cddfSDavid du Colombier 
342*7dd7cddfSDavid du Colombier 	for (i = 0; i < r_size(op - 1); i++)
343*7dd7cddfSDavid du Colombier 	    gs_debug[op[-1].value.bytes[i] & 127] =
344*7dd7cddfSDavid du Colombier 		op->value.boolval;
345*7dd7cddfSDavid du Colombier     }
346*7dd7cddfSDavid du Colombier     pop(2);
347*7dd7cddfSDavid du Colombier     return 0;
348*7dd7cddfSDavid du Colombier }
349*7dd7cddfSDavid du Colombier 
350*7dd7cddfSDavid du Colombier /* ------ Initialization procedure ------ */
351*7dd7cddfSDavid du Colombier 
352*7dd7cddfSDavid du Colombier const op_def zmisc_op_defs[] =
353*7dd7cddfSDavid du Colombier {
354*7dd7cddfSDavid du Colombier     {"1bind", zbind},
355*7dd7cddfSDavid du Colombier     {"1getenv", zgetenv},
356*7dd7cddfSDavid du Colombier     {"2.makeoperator", zmakeoperator},
357*7dd7cddfSDavid du Colombier     {"0.oserrno", zoserrno},
358*7dd7cddfSDavid du Colombier     {"1.oserrorstring", zoserrorstring},
359*7dd7cddfSDavid du Colombier     {"0realtime", zrealtime},
360*7dd7cddfSDavid du Colombier     {"1serialnumber", zserialnumber},
361*7dd7cddfSDavid du Colombier     {"2.setdebug", zsetdebug},
362*7dd7cddfSDavid du Colombier     {"1.setoserrno", zsetoserrno},
363*7dd7cddfSDavid du Colombier     {"0usertime", zusertime},
364*7dd7cddfSDavid du Colombier     op_def_end(0)
365*7dd7cddfSDavid du Colombier };
366