1
2 /* Copyright (C) 1996, 2000 Aladdin Enterprises. All rights reserved.
3
4 This software is provided AS-IS with no warranty, either express or
5 implied.
6
7 This software is distributed under license and may not be copied,
8 modified or distributed except as expressly authorized under the terms
9 of the license contained in the file LICENSE in this distribution.
10
11 For more information about licensing, please refer to
12 http://www.ghostscript.com/licensing/. For information on
13 commercial licensing, go to http://www.artifex.com/licensing/ or
14 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
15 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
16 */
17
18 /* $Id: zusparam.c,v 1.13 2004/08/04 19:36:13 stefan Exp $ */
19 /* User and system parameter operators */
20 #include "memory_.h"
21 #include "string_.h"
22 #include "ghost.h"
23 #include "oper.h"
24 #include "gscdefs.h"
25 #include "gsstruct.h" /* for gxht.h */
26 #include "gsfont.h" /* for user params */
27 #include "gxht.h" /* for user params */
28 #include "gsutil.h"
29 #include "estack.h"
30 #include "ialloc.h" /* for imemory for status */
31 #include "icontext.h" /* for set_user_params prototype */
32 #include "idict.h"
33 #include "idparam.h"
34 #include "iparam.h"
35 #include "dstack.h"
36 #include "iname.h"
37 #include "itoken.h"
38 #include "iutil2.h"
39 #include "ivmem2.h"
40 #include "store.h"
41
42 /* The (global) font directory */
43 extern gs_font_dir *ifont_dir; /* in zfont.c */
44
45 /* Define an individual user or system parameter. */
46 /* Eventually this will be made public. */
47 #define param_def_common\
48 const char *pname
49
50 typedef struct param_def_s {
51 param_def_common;
52 } param_def_t;
53
54 typedef struct long_param_def_s {
55 param_def_common;
56 long min_value, max_value;
57 long (*current)(i_ctx_t *);
58 int (*set)(i_ctx_t *, long);
59 } long_param_def_t;
60
61 #if arch_sizeof_long > arch_sizeof_int
62 # define MAX_UINT_PARAM max_uint
63 #else
64 # define MAX_UINT_PARAM max_long
65 #endif
66
67 typedef struct bool_param_def_s {
68 param_def_common;
69 bool (*current)(i_ctx_t *);
70 int (*set)(i_ctx_t *, bool);
71 } bool_param_def_t;
72
73 typedef struct string_param_def_s {
74 param_def_common;
75 void (*current)(i_ctx_t *, gs_param_string *);
76 int (*set)(i_ctx_t *, gs_param_string *);
77 } string_param_def_t;
78
79 /* Define a parameter set (user or system). */
80 typedef struct param_set_s {
81 const long_param_def_t *long_defs;
82 uint long_count;
83 const bool_param_def_t *bool_defs;
84 uint bool_count;
85 const string_param_def_t *string_defs;
86 uint string_count;
87 } param_set;
88
89 /* Forward references */
90 private int setparams(i_ctx_t *, gs_param_list *, const param_set *);
91 private int currentparams(i_ctx_t *, const param_set *);
92 private int currentparam1(i_ctx_t *, const param_set *);
93
94 /* ------ Passwords ------ */
95
96 /* <string|int> .checkpassword <0|1|2> */
97 private int
zcheckpassword(i_ctx_t * i_ctx_p)98 zcheckpassword(i_ctx_t *i_ctx_p)
99 {
100 os_ptr op = osp;
101 ref params[2];
102 array_param_list list;
103 gs_param_list *const plist = (gs_param_list *)&list;
104 int result = 0;
105 int code = name_ref(imemory, (const byte *)"Password", 8, ¶ms[0], 0);
106 password pass;
107
108 if (code < 0)
109 return code;
110 params[1] = *op;
111 array_param_list_read(&list, params, 2, NULL, false, iimemory);
112 if (dict_read_password(&pass, systemdict, "StartJobPassword") >= 0 &&
113 param_check_password(plist, &pass) == 0
114 )
115 result = 1;
116 if (dict_read_password(&pass, systemdict, "SystemParamsPassword") >= 0 &&
117 param_check_password(plist, &pass) == 0
118 )
119 result = 2;
120 iparam_list_release(&list);
121 make_int(op, result);
122 return 0;
123 }
124
125 /* ------ System parameters ------ */
126
127 /* Integer values */
128 private long
current_BuildTime(i_ctx_t * i_ctx_p)129 current_BuildTime(i_ctx_t *i_ctx_p)
130 {
131 return gs_buildtime;
132 }
133 private long
current_MaxFontCache(i_ctx_t * i_ctx_p)134 current_MaxFontCache(i_ctx_t *i_ctx_p)
135 {
136 return gs_currentcachesize(ifont_dir);
137 }
138 private int
set_MaxFontCache(i_ctx_t * i_ctx_p,long val)139 set_MaxFontCache(i_ctx_t *i_ctx_p, long val)
140 {
141 return gs_setcachesize(ifont_dir,
142 (uint)(val < 0 ? 0 : val > max_uint ? max_uint :
143 val));
144 }
145 private long
current_CurFontCache(i_ctx_t * i_ctx_p)146 current_CurFontCache(i_ctx_t *i_ctx_p)
147 {
148 uint cstat[7];
149
150 gs_cachestatus(ifont_dir, cstat);
151 return cstat[0];
152 }
153 private long
current_MaxGlobalVM(i_ctx_t * i_ctx_p)154 current_MaxGlobalVM(i_ctx_t *i_ctx_p)
155 {
156 gs_memory_gc_status_t stat;
157
158 gs_memory_gc_status(iimemory_global, &stat);
159 return stat.max_vm;
160 }
161 private int
set_MaxGlobalVM(i_ctx_t * i_ctx_p,long val)162 set_MaxGlobalVM(i_ctx_t *i_ctx_p, long val)
163 {
164 gs_memory_gc_status_t stat;
165
166 gs_memory_gc_status(iimemory_global, &stat);
167 stat.max_vm = max(val, 0);
168 gs_memory_set_gc_status(iimemory_global, &stat);
169 return 0;
170 }
171 private long
current_Revision(i_ctx_t * i_ctx_p)172 current_Revision(i_ctx_t *i_ctx_p)
173 {
174 return gs_revision;
175 }
176 private const long_param_def_t system_long_params[] =
177 {
178 {"BuildTime", min_long, max_long, current_BuildTime, NULL},
179 {"MaxFontCache", 0, MAX_UINT_PARAM, current_MaxFontCache, set_MaxFontCache},
180 {"CurFontCache", 0, MAX_UINT_PARAM, current_CurFontCache, NULL},
181 {"Revision", min_long, max_long, current_Revision, NULL},
182 /* Extensions */
183 {"MaxGlobalVM", 0, max_long, current_MaxGlobalVM, set_MaxGlobalVM}
184 };
185
186 /* Boolean values */
187 private bool
current_ByteOrder(i_ctx_t * i_ctx_p)188 current_ByteOrder(i_ctx_t *i_ctx_p)
189 {
190 return !arch_is_big_endian;
191 }
192 private const bool_param_def_t system_bool_params[] =
193 {
194 {"ByteOrder", current_ByteOrder, NULL}
195 };
196
197 /* String values */
198 private void
current_RealFormat(i_ctx_t * i_ctx_p,gs_param_string * pval)199 current_RealFormat(i_ctx_t *i_ctx_p, gs_param_string * pval)
200 {
201 #if arch_floats_are_IEEE
202 static const char *const rfs = "IEEE";
203 #else
204 static const char *const rfs = "not IEEE";
205 #endif
206
207 pval->data = (const byte *)rfs;
208 pval->size = strlen(rfs);
209 pval->persistent = true;
210 }
211 private const string_param_def_t system_string_params[] =
212 {
213 {"RealFormat", current_RealFormat, NULL}
214 };
215
216 /* The system parameter set */
217 private const param_set system_param_set =
218 {
219 system_long_params, countof(system_long_params),
220 system_bool_params, countof(system_bool_params),
221 system_string_params, countof(system_string_params)
222 };
223
224 /* <dict> .setsystemparams - */
225 private int
zsetsystemparams(i_ctx_t * i_ctx_p)226 zsetsystemparams(i_ctx_t *i_ctx_p)
227 {
228 os_ptr op = osp;
229 int code;
230 dict_param_list list;
231 gs_param_list *const plist = (gs_param_list *)&list;
232 password pass;
233
234 check_type(*op, t_dictionary);
235 code = dict_param_list_read(&list, op, NULL, false, iimemory);
236 if (code < 0)
237 return code;
238 code = dict_read_password(&pass, systemdict, "SystemParamsPassword");
239 if (code < 0)
240 return code;
241 code = param_check_password(plist, &pass);
242 if (code != 0) {
243 if (code > 0)
244 code = gs_note_error(e_invalidaccess);
245 goto out;
246 }
247 code = param_read_password(plist, "StartJobPassword", &pass);
248 switch (code) {
249 default: /* invalid */
250 goto out;
251 case 1: /* missing */
252 break;
253 case 0:
254 code = dict_write_password(&pass, systemdict,
255 "StartJobPassword",
256 ! i_ctx_p->LockFilePermissions);
257 if (code < 0)
258 goto out;
259 }
260 code = param_read_password(plist, "SystemParamsPassword", &pass);
261 switch (code) {
262 default: /* invalid */
263 goto out;
264 case 1: /* missing */
265 break;
266 case 0:
267 code = dict_write_password(&pass, systemdict,
268 "SystemParamsPassword",
269 ! i_ctx_p->LockFilePermissions);
270 if (code < 0)
271 goto out;
272 }
273 code = setparams(i_ctx_p, plist, &system_param_set);
274 out:
275 iparam_list_release(&list);
276 if (code < 0)
277 return code;
278 pop(1);
279 return 0;
280 }
281
282 /* - .currentsystemparams <name1> <value1> ... */
283 private int
zcurrentsystemparams(i_ctx_t * i_ctx_p)284 zcurrentsystemparams(i_ctx_t *i_ctx_p)
285 {
286 return currentparams(i_ctx_p, &system_param_set);
287 }
288
289 /* <name> .getsystemparam <value> */
290 private int
zgetsystemparam(i_ctx_t * i_ctx_p)291 zgetsystemparam(i_ctx_t *i_ctx_p)
292 {
293 return currentparam1(i_ctx_p, &system_param_set);
294 }
295
296 /* ------ User parameters ------ */
297
298 /* Integer values */
299 private long
current_JobTimeout(i_ctx_t * i_ctx_p)300 current_JobTimeout(i_ctx_t *i_ctx_p)
301 {
302 return 0;
303 }
304 private int
set_JobTimeout(i_ctx_t * i_ctx_p,long val)305 set_JobTimeout(i_ctx_t *i_ctx_p, long val)
306 {
307 return 0;
308 }
309 private long
current_MaxFontItem(i_ctx_t * i_ctx_p)310 current_MaxFontItem(i_ctx_t *i_ctx_p)
311 {
312 return gs_currentcacheupper(ifont_dir);
313 }
314 private int
set_MaxFontItem(i_ctx_t * i_ctx_p,long val)315 set_MaxFontItem(i_ctx_t *i_ctx_p, long val)
316 {
317 return gs_setcacheupper(ifont_dir, val);
318 }
319 private long
current_MinFontCompress(i_ctx_t * i_ctx_p)320 current_MinFontCompress(i_ctx_t *i_ctx_p)
321 {
322 return gs_currentcachelower(ifont_dir);
323 }
324 private int
set_MinFontCompress(i_ctx_t * i_ctx_p,long val)325 set_MinFontCompress(i_ctx_t *i_ctx_p, long val)
326 {
327 return gs_setcachelower(ifont_dir, val);
328 }
329 private long
current_MaxOpStack(i_ctx_t * i_ctx_p)330 current_MaxOpStack(i_ctx_t *i_ctx_p)
331 {
332 return ref_stack_max_count(&o_stack);
333 }
334 private int
set_MaxOpStack(i_ctx_t * i_ctx_p,long val)335 set_MaxOpStack(i_ctx_t *i_ctx_p, long val)
336 {
337 return ref_stack_set_max_count(&o_stack, val);
338 }
339 private long
current_MaxDictStack(i_ctx_t * i_ctx_p)340 current_MaxDictStack(i_ctx_t *i_ctx_p)
341 {
342 return ref_stack_max_count(&d_stack);
343 }
344 private int
set_MaxDictStack(i_ctx_t * i_ctx_p,long val)345 set_MaxDictStack(i_ctx_t *i_ctx_p, long val)
346 {
347 return ref_stack_set_max_count(&d_stack, val);
348 }
349 private long
current_MaxExecStack(i_ctx_t * i_ctx_p)350 current_MaxExecStack(i_ctx_t *i_ctx_p)
351 {
352 return ref_stack_max_count(&e_stack);
353 }
354 private int
set_MaxExecStack(i_ctx_t * i_ctx_p,long val)355 set_MaxExecStack(i_ctx_t *i_ctx_p, long val)
356 {
357 return ref_stack_set_max_count(&e_stack, val);
358 }
359 private long
current_MaxLocalVM(i_ctx_t * i_ctx_p)360 current_MaxLocalVM(i_ctx_t *i_ctx_p)
361 {
362 gs_memory_gc_status_t stat;
363
364 gs_memory_gc_status(iimemory_local, &stat);
365 return stat.max_vm;
366 }
367 private int
set_MaxLocalVM(i_ctx_t * i_ctx_p,long val)368 set_MaxLocalVM(i_ctx_t *i_ctx_p, long val)
369 {
370 gs_memory_gc_status_t stat;
371
372 gs_memory_gc_status(iimemory_local, &stat);
373 stat.max_vm = max(val, 0);
374 gs_memory_set_gc_status(iimemory_local, &stat);
375 return 0;
376 }
377 private long
current_VMReclaim(i_ctx_t * i_ctx_p)378 current_VMReclaim(i_ctx_t *i_ctx_p)
379 {
380 gs_memory_gc_status_t gstat, lstat;
381
382 gs_memory_gc_status(iimemory_global, &gstat);
383 gs_memory_gc_status(iimemory_local, &lstat);
384 return (!gstat.enabled ? -2 : !lstat.enabled ? -1 : 0);
385 }
386 private long
current_VMThreshold(i_ctx_t * i_ctx_p)387 current_VMThreshold(i_ctx_t *i_ctx_p)
388 {
389 gs_memory_gc_status_t stat;
390
391 gs_memory_gc_status(iimemory_local, &stat);
392 return stat.vm_threshold;
393 }
394 private long
current_WaitTimeout(i_ctx_t * i_ctx_p)395 current_WaitTimeout(i_ctx_t *i_ctx_p)
396 {
397 return 0;
398 }
399 private int
set_WaitTimeout(i_ctx_t * i_ctx_p,long val)400 set_WaitTimeout(i_ctx_t *i_ctx_p, long val)
401 {
402 return 0;
403 }
404 private long
current_MinScreenLevels(i_ctx_t * i_ctx_p)405 current_MinScreenLevels(i_ctx_t *i_ctx_p)
406 {
407 return gs_currentminscreenlevels();
408 }
409 private int
set_MinScreenLevels(i_ctx_t * i_ctx_p,long val)410 set_MinScreenLevels(i_ctx_t *i_ctx_p, long val)
411 {
412 gs_setminscreenlevels((uint) val);
413 return 0;
414 }
415 private long
current_AlignToPixels(i_ctx_t * i_ctx_p)416 current_AlignToPixels(i_ctx_t *i_ctx_p)
417 {
418 return gs_currentaligntopixels(ifont_dir);
419 }
420 private int
set_AlignToPixels(i_ctx_t * i_ctx_p,long val)421 set_AlignToPixels(i_ctx_t *i_ctx_p, long val)
422 {
423 gs_setaligntopixels(ifont_dir, (uint)val);
424 return 0;
425 }
426 private long
current_GridFitTT(i_ctx_t * i_ctx_p)427 current_GridFitTT(i_ctx_t *i_ctx_p)
428 {
429 return gs_currentgridfittt(ifont_dir);
430 }
431 private int
set_GridFitTT(i_ctx_t * i_ctx_p,long val)432 set_GridFitTT(i_ctx_t *i_ctx_p, long val)
433 {
434 gs_setgridfittt(ifont_dir, (uint)val);
435 return 0;
436 }
437 private const long_param_def_t user_long_params[] =
438 {
439 {"JobTimeout", 0, MAX_UINT_PARAM,
440 current_JobTimeout, set_JobTimeout},
441 {"MaxFontItem", 0, MAX_UINT_PARAM,
442 current_MaxFontItem, set_MaxFontItem},
443 {"MinFontCompress", 0, MAX_UINT_PARAM,
444 current_MinFontCompress, set_MinFontCompress},
445 {"MaxOpStack", 0, MAX_UINT_PARAM,
446 current_MaxOpStack, set_MaxOpStack},
447 {"MaxDictStack", 0, MAX_UINT_PARAM,
448 current_MaxDictStack, set_MaxDictStack},
449 {"MaxExecStack", 0, MAX_UINT_PARAM,
450 current_MaxExecStack, set_MaxExecStack},
451 {"MaxLocalVM", 0, max_long,
452 current_MaxLocalVM, set_MaxLocalVM},
453 {"VMReclaim", -2, 0,
454 current_VMReclaim, set_vm_reclaim},
455 {"VMThreshold", -1, max_long,
456 current_VMThreshold, set_vm_threshold},
457 {"WaitTimeout", 0, MAX_UINT_PARAM,
458 current_WaitTimeout, set_WaitTimeout},
459 /* Extensions */
460 {"MinScreenLevels", 0, MAX_UINT_PARAM,
461 current_MinScreenLevels, set_MinScreenLevels},
462 {"AlignToPixels", 0, 1,
463 current_AlignToPixels, set_AlignToPixels},
464 {"GridFitTT", 0, 3,
465 current_GridFitTT, set_GridFitTT}
466 };
467
468 /* Boolean values */
469 private bool
current_AccurateScreens(i_ctx_t * i_ctx_p)470 current_AccurateScreens(i_ctx_t *i_ctx_p)
471 {
472 return gs_currentaccuratescreens();
473 }
474 private int
set_AccurateScreens(i_ctx_t * i_ctx_p,bool val)475 set_AccurateScreens(i_ctx_t *i_ctx_p, bool val)
476 {
477 gs_setaccuratescreens(val);
478 return 0;
479 }
480 /* Boolean values */
481 private bool
current_UseWTS(i_ctx_t * i_ctx_p)482 current_UseWTS(i_ctx_t *i_ctx_p)
483 {
484 return gs_currentusewts();
485 }
486 private int
set_UseWTS(i_ctx_t * i_ctx_p,bool val)487 set_UseWTS(i_ctx_t *i_ctx_p, bool val)
488 {
489 gs_setusewts(val);
490 return 0;
491 }
492 private bool
current_LockFilePermissions(i_ctx_t * i_ctx_p)493 current_LockFilePermissions(i_ctx_t *i_ctx_p)
494 {
495 return i_ctx_p->LockFilePermissions;
496 }
497 private int
set_LockFilePermissions(i_ctx_t * i_ctx_p,bool val)498 set_LockFilePermissions(i_ctx_t *i_ctx_p, bool val)
499 {
500 /* allow locking even if already locked */
501 if (i_ctx_p->LockFilePermissions && !val)
502 return_error(e_invalidaccess);
503 i_ctx_p->LockFilePermissions = val;
504 return 0;
505 }
506 private const bool_param_def_t user_bool_params[] =
507 {
508 {"AccurateScreens", current_AccurateScreens, set_AccurateScreens},
509 {"UseWTS", current_UseWTS, set_UseWTS},
510 {"LockFilePermissions", current_LockFilePermissions, set_LockFilePermissions}
511 };
512
513 /* The user parameter set */
514 private const param_set user_param_set =
515 {
516 user_long_params, countof(user_long_params),
517 user_bool_params, countof(user_bool_params),
518 0, 0
519 };
520
521 /* <dict> .setuserparams - */
522 /* We break this out for use when switching contexts. */
523 int
set_user_params(i_ctx_t * i_ctx_p,const ref * paramdict)524 set_user_params(i_ctx_t *i_ctx_p, const ref *paramdict)
525 {
526 dict_param_list list;
527 int code;
528
529 check_type(*paramdict, t_dictionary);
530 code = dict_param_list_read(&list, paramdict, NULL, false, iimemory);
531 if (code < 0)
532 return code;
533 code = setparams(i_ctx_p, (gs_param_list *)&list, &user_param_set);
534 iparam_list_release(&list);
535 return code;
536 }
537 private int
zsetuserparams(i_ctx_t * i_ctx_p)538 zsetuserparams(i_ctx_t *i_ctx_p)
539 {
540 os_ptr op = osp;
541 int code = set_user_params(i_ctx_p, op);
542
543 if (code >= 0) {
544 /* Update cached scanner options. */
545 i_ctx_p->scanner_options =
546 ztoken_scanner_options(op, i_ctx_p->scanner_options);
547 pop(1);
548 }
549 return code;
550 }
551
552 /* - .currentuserparams <name1> <value1> ... */
553 private int
zcurrentuserparams(i_ctx_t * i_ctx_p)554 zcurrentuserparams(i_ctx_t *i_ctx_p)
555 {
556 return currentparams(i_ctx_p, &user_param_set);
557 }
558
559 /* <name> .getuserparam <value> */
560 private int
zgetuserparam(i_ctx_t * i_ctx_p)561 zgetuserparam(i_ctx_t *i_ctx_p)
562 {
563 return currentparam1(i_ctx_p, &user_param_set);
564 }
565
566 /* ------ Initialization procedure ------ */
567
568 const op_def zusparam_op_defs[] =
569 {
570 /* User and system parameters are accessible even in Level 1 */
571 /* (if this is a Level 2 system). */
572 {"0.currentsystemparams", zcurrentsystemparams},
573 {"0.currentuserparams", zcurrentuserparams},
574 {"1.getsystemparam", zgetsystemparam},
575 {"1.getuserparam", zgetuserparam},
576 {"1.setsystemparams", zsetsystemparams},
577 {"1.setuserparams", zsetuserparams},
578 /* The rest of the operators are defined only in Level 2. */
579 op_def_begin_level2(),
580 {"1.checkpassword", zcheckpassword},
581 op_def_end(0)
582 };
583
584 /* ------ Internal procedures ------ */
585
586 /* Set the values of a parameter set from a parameter list. */
587 /* We don't attempt to back out if anything fails. */
588 private int
setparams(i_ctx_t * i_ctx_p,gs_param_list * plist,const param_set * pset)589 setparams(i_ctx_t *i_ctx_p, gs_param_list * plist, const param_set * pset)
590 {
591 int i, code;
592
593 for (i = 0; i < pset->long_count; i++) {
594 const long_param_def_t *pdef = &pset->long_defs[i];
595 long val;
596
597 if (pdef->set == NULL)
598 continue;
599 code = param_read_long(plist, pdef->pname, &val);
600 switch (code) {
601 default: /* invalid */
602 return code;
603 case 1: /* missing */
604 break;
605 case 0:
606 if (val < pdef->min_value || val > pdef->max_value)
607 return_error(e_rangecheck);
608 code = (*pdef->set)(i_ctx_p, val);
609 if (code < 0)
610 return code;
611 }
612 }
613 for (i = 0; i < pset->bool_count; i++) {
614 const bool_param_def_t *pdef = &pset->bool_defs[i];
615 bool val;
616
617 if (pdef->set == NULL)
618 continue;
619 code = param_read_bool(plist, pdef->pname, &val);
620 if (code == 0)
621 code = (*pdef->set)(i_ctx_p, val);
622 if (code < 0)
623 return code;
624 }
625 /****** WE SHOULD DO STRINGS AND STRING ARRAYS, BUT WE DON'T YET ******/
626 return 0;
627 }
628
629 /* Get the current values of a parameter set to the stack. */
630 private bool
pname_matches(const char * pname,const ref * psref)631 pname_matches(const char *pname, const ref * psref)
632 {
633 return
634 (psref == 0 ||
635 !bytes_compare((const byte *)pname, strlen(pname),
636 psref->value.const_bytes, r_size(psref)));
637 }
638 private int
current_param_list(i_ctx_t * i_ctx_p,const param_set * pset,const ref * psref)639 current_param_list(i_ctx_t *i_ctx_p, const param_set * pset,
640 const ref * psref /*t_string */ )
641 {
642 stack_param_list list;
643 gs_param_list *const plist = (gs_param_list *)&list;
644 int i;
645
646 stack_param_list_write(&list, &o_stack, NULL, iimemory);
647 for (i = 0; i < pset->long_count; i++) {
648 const char *pname = pset->long_defs[i].pname;
649
650 if (pname_matches(pname, psref)) {
651 long val = (*pset->long_defs[i].current)(i_ctx_p);
652 int code = param_write_long(plist, pname, &val);
653
654 if (code < 0)
655 return code;
656 }
657 }
658 for (i = 0; i < pset->bool_count; i++) {
659 const char *pname = pset->bool_defs[i].pname;
660
661 if (pname_matches(pname, psref)) {
662 bool val = (*pset->bool_defs[i].current)(i_ctx_p);
663 int code = param_write_bool(plist, pname, &val);
664
665 if (code < 0)
666 return code;
667 }
668 }
669 for (i = 0; i < pset->string_count; i++) {
670 const char *pname = pset->string_defs[i].pname;
671
672 if (pname_matches(pname, psref)) {
673 gs_param_string val;
674 int code;
675
676 (*pset->string_defs[i].current)(i_ctx_p, &val);
677 code = param_write_string(plist, pname, &val);
678 if (code < 0)
679 return code;
680 }
681 }
682 return 0;
683 }
684
685 /* Get the current values of a parameter set to the stack. */
686 private int
currentparams(i_ctx_t * i_ctx_p,const param_set * pset)687 currentparams(i_ctx_t *i_ctx_p, const param_set * pset)
688 {
689 return current_param_list(i_ctx_p, pset, NULL);
690 }
691
692 /* Get the value of a single parameter to the stack, or signal an error. */
693 private int
currentparam1(i_ctx_t * i_ctx_p,const param_set * pset)694 currentparam1(i_ctx_t *i_ctx_p, const param_set * pset)
695 {
696 os_ptr op = osp;
697 ref sref;
698 int code;
699
700 check_type(*op, t_name);
701 check_ostack(2);
702 name_string_ref(imemory, (const ref *)op, &sref);
703 code = current_param_list(i_ctx_p, pset, &sref);
704 if (code < 0)
705 return code;
706 if (osp == op)
707 return_error(e_undefined);
708 /* We know osp == op + 2. */
709 ref_assign(op, op + 2);
710 pop(2);
711 return code;
712 }
713