Coverage Report

Created: 2026-09-14 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/psi/zusparam.c
Line
Count
Source
1
/* Copyright (C) 2001-2026 Artifex Software, Inc.
2
   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
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* User and system parameter operators */
18
#include "memory_.h"
19
#include "string_.h"
20
#include "ghost.h"
21
#include "oper.h"
22
#include "gscdefs.h"
23
#include "gsstruct.h"   /* for gxht.h */
24
#include "gsfont.h"   /* for user params */
25
#include "gxht.h"   /* for user params */
26
#include "gsutil.h"
27
#include "estack.h"
28
#include "ialloc.h"   /* for imemory for status */
29
#include "icontext.h"   /* for set_user_params prototype */
30
#include "idict.h"
31
#include "idparam.h"
32
#include "iparam.h"
33
#include "dstack.h"
34
#include "iname.h"
35
#include "itoken.h"
36
#include "iutil2.h"
37
#include "ivmem2.h"
38
#include "store.h"
39
#include "gsnamecl.h"
40
#include "igstate.h"
41
#include "gscms.h"
42
#include "gsicc_manage.h"
43
#include "gsparamx.h"
44
#include "gx.h"
45
#include "gxgstate.h"
46
#include "gslibctx.h"
47
#include "ichar.h"
48
49
/* The (global) font directory */
50
extern gs_font_dir *ifont_dir;  /* in zfont.c */
51
52
/* Define an individual user or system parameter. */
53
/* Eventually this will be made public. */
54
#define param_def_common\
55
    const char *pname
56
57
typedef struct param_def_s {
58
    param_def_common;
59
} param_def_t;
60
61
typedef struct size_t_param_def_s {
62
    param_def_common;
63
    size_t min_value, max_value;
64
    size_t (*current)(i_ctx_t *);
65
    int (*set)(i_ctx_t *, size_t);
66
} size_t_param_def_t;
67
68
typedef struct i64_param_def_s {
69
    param_def_common;
70
    int64_t min_value, max_value;
71
    int64_t (*current)(i_ctx_t *);
72
    int (*set)(i_ctx_t *, int64_t);
73
} i64_param_def_t;
74
75
typedef struct long_param_def_s {
76
    param_def_common;
77
    long min_value, max_value;
78
    long (*current)(i_ctx_t *);
79
    int (*set)(i_ctx_t *, long);
80
} long_param_def_t;
81
82
#if ARCH_SIZEOF_LONG > ARCH_SIZEOF_INT
83
#  define MAX_UINT_PARAM max_uint
84
#  define MIN_INT_PARAM min_int
85
#else
86
#  define MAX_UINT_PARAM max_long
87
#  define MIN_INT_PARAM min_long
88
#endif
89
90
typedef struct bool_param_def_s {
91
    param_def_common;
92
    bool (*current)(i_ctx_t *);
93
    int (*set)(i_ctx_t *, bool);
94
} bool_param_def_t;
95
96
typedef struct string_param_def_s {
97
    param_def_common;
98
    void (*current)(i_ctx_t *, gs_param_string *);
99
    int (*set)(i_ctx_t *, gs_param_string *);
100
} string_param_def_t;
101
102
/* Define a parameter set (user or system). */
103
typedef struct param_set_s {
104
    const size_t_param_def_t *size_t_defs;
105
    uint size_t_count;
106
    const i64_param_def_t *i64_defs;
107
    uint i64_count;
108
    const long_param_def_t *long_defs;
109
    uint long_count;
110
    const bool_param_def_t *bool_defs;
111
    uint bool_count;
112
    const string_param_def_t *string_defs;
113
    uint string_count;
114
} param_set;
115
116
/* Forward references */
117
static int setparams(i_ctx_t *, gs_param_list *, const param_set *);
118
static int currentparams(i_ctx_t *, const param_set *);
119
static int currentparam1(i_ctx_t *, const param_set *);
120
121
/* ------ Passwords ------ */
122
123
/* <string|int> .checkpassword <0|1|2> */
124
static int
125
zcheckpassword(i_ctx_t *i_ctx_p)
126
7.25k
{
127
7.25k
    os_ptr op = osp;
128
7.25k
    ref params[2];
129
7.25k
    array_param_list list;
130
7.25k
    gs_param_list *const plist = (gs_param_list *)&list;
131
7.25k
    int result = 0;
132
7.25k
    int code = name_ref(imemory, (const byte *)"Password", 8, &params[0], 0);
133
7.25k
    password pass;
134
135
7.25k
    if (code < 0)
136
0
        return code;
137
7.25k
    check_op(1);
138
7.25k
    params[1] = *op;
139
7.25k
    array_param_list_read(&list, params, 2, NULL, false, iimemory);
140
7.25k
    if (dict_read_password(&pass, systemdict, "StartJobPassword") >= 0 &&
141
0
        param_check_password(plist, &pass) == 0
142
7.25k
        )
143
0
        result = 1;
144
145
7.25k
    if (i_ctx_p->system_params.SystemParamsPassword != NULL && strlen(i_ctx_p->system_params.SystemParamsPassword) < 64) {
146
0
        memcpy(pass.data, i_ctx_p->system_params.SystemParamsPassword, strlen(i_ctx_p->system_params.SystemParamsPassword));;
147
0
        pass.size = strlen(i_ctx_p->system_params.SystemParamsPassword);
148
7.25k
    } else {
149
7.25k
        pass.data[0] = 0x00;
150
7.25k
        pass.size = 0;
151
7.25k
    }
152
7.25k
    if (param_check_password(plist, &pass) == 0)
153
7.25k
        result = 2;
154
155
7.25k
    iparam_list_release(&list);
156
7.25k
    make_int(op, result);
157
7.25k
    return 0;
158
7.25k
}
159
160
/* ------ System parameters ------ */
161
162
/* Integer values */
163
static long
164
current_BuildTime(i_ctx_t *i_ctx_p)
165
2.37M
{
166
2.37M
    return gs_buildtime;
167
2.37M
}
168
169
static long
170
current_CurDisplayList(i_ctx_t *i_ctx_p)
171
2.37M
{
172
2.37M
    return i_ctx_p->system_params.CurDisplayList;
173
2.37M
}
174
175
static long
176
current_CurFormCache(i_ctx_t *i_ctx_p)
177
2.37M
{
178
2.37M
    return i_ctx_p->system_params.CurFormCache;
179
2.37M
}
180
181
static long
182
current_CurOutlineCache(i_ctx_t *i_ctx_p)
183
2.37M
{
184
2.37M
    return i_ctx_p->system_params.CurOutlineCache;
185
2.37M
}
186
187
static long
188
current_CurPatternCache(i_ctx_t *i_ctx_p)
189
2.37M
{
190
2.37M
    return i_ctx_p->system_params.CurPatternCache;
191
2.37M
}
192
193
static long
194
current_CurScreenStorage(i_ctx_t *i_ctx_p)
195
2.37M
{
196
2.37M
    return i_ctx_p->system_params.CurScreenStorage;
197
2.37M
}
198
199
static long
200
current_CurSourceList(i_ctx_t *i_ctx_p)
201
2.37M
{
202
2.37M
    return i_ctx_p->system_params.CurSourceList;
203
2.37M
}
204
205
static long
206
current_CurStoredScreenCache(i_ctx_t *i_ctx_p)
207
2.37M
{
208
2.37M
    return i_ctx_p->system_params.CurStoredScreenCache;
209
2.37M
}
210
211
static long
212
current_CurUPathCache(i_ctx_t *i_ctx_p)
213
2.37M
{
214
2.37M
    return i_ctx_p->system_params.CurScreenStorage;
215
2.37M
}
216
217
static long
218
current_MaxDisplayAndSourceList(i_ctx_t *i_ctx_p)
219
2.37M
{
220
2.37M
    return i_ctx_p->system_params.MaxDisplayAndSourceList;
221
2.37M
}
222
223
static int
224
set_MaxDisplayAndSourceList(i_ctx_t *i_ctx_p, long val)
225
0
{
226
0
    i_ctx_p->system_params.MaxDisplayAndSourceList = val;
227
0
    return 0;
228
0
}
229
230
static long
231
current_MaxDisplayList(i_ctx_t *i_ctx_p)
232
2.37M
{
233
2.37M
    return i_ctx_p->system_params.MaxDisplayList;
234
2.37M
}
235
236
static int
237
set_MaxDisplayList(i_ctx_t *i_ctx_p, long val)
238
0
{
239
0
    i_ctx_p->system_params.MaxDisplayList = val;
240
0
    return 0;
241
0
}
242
243
static long
244
current_MaxFormCache(i_ctx_t *i_ctx_p)
245
2.37M
{
246
2.37M
    return i_ctx_p->system_params.MaxFormCache;
247
2.37M
}
248
249
static int
250
set_MaxFormCache(i_ctx_t *i_ctx_p, long val)
251
0
{
252
0
    i_ctx_p->system_params.MaxFormCache = val;
253
0
    return 0;
254
0
}
255
256
static long
257
current_MaxImageBuffer(i_ctx_t *i_ctx_p)
258
2.37M
{
259
2.37M
    return i_ctx_p->system_params.MaxImageBuffer;
260
2.37M
}
261
262
static int
263
set_MaxImageBuffer(i_ctx_t *i_ctx_p, long val)
264
0
{
265
0
    i_ctx_p->system_params.MaxImageBuffer = val;
266
0
    return 0;
267
0
}
268
269
static long
270
current_MaxOutlineCache(i_ctx_t *i_ctx_p)
271
2.37M
{
272
2.37M
    return i_ctx_p->system_params.MaxOutlineCache;
273
2.37M
}
274
275
static int
276
set_MaxOutlineCache(i_ctx_t *i_ctx_p, long val)
277
0
{
278
0
    i_ctx_p->system_params.MaxOutlineCache = val;
279
0
    return 0;
280
0
}
281
282
static long
283
current_MaxPatternCache(i_ctx_t *i_ctx_p)
284
2.37M
{
285
2.37M
    return i_ctx_p->system_params.MaxPatternCache;
286
2.37M
}
287
288
static int
289
set_MaxPatternCache(i_ctx_t *i_ctx_p, long val)
290
0
{
291
0
    i_ctx_p->system_params.MaxPatternCache = val;
292
0
    return 0;
293
0
}
294
295
static long
296
current_MaxUPathCache(i_ctx_t *i_ctx_p)
297
2.37M
{
298
2.37M
    return i_ctx_p->system_params.MaxUPathCache;
299
2.37M
}
300
301
static int
302
set_MaxUPathCache(i_ctx_t *i_ctx_p, long val)
303
0
{
304
0
    i_ctx_p->system_params.MaxUPathCache = val;
305
0
    return 0;
306
0
}
307
308
static long
309
current_MaxScreenStorage(i_ctx_t *i_ctx_p)
310
2.37M
{
311
2.37M
    return i_ctx_p->system_params.MaxScreenStorage;
312
2.37M
}
313
314
static int
315
set_MaxScreenStorage(i_ctx_t *i_ctx_p, long val)
316
0
{
317
0
    i_ctx_p->system_params.MaxScreenStorage = val;
318
0
    return 0;
319
0
}
320
321
static long
322
current_MaxSourceList(i_ctx_t *i_ctx_p)
323
2.37M
{
324
2.37M
    return i_ctx_p->system_params.MaxSourceList;
325
2.37M
}
326
327
static int
328
set_MaxSourceList(i_ctx_t *i_ctx_p, long val)
329
0
{
330
0
    i_ctx_p->system_params.MaxSourceList = val;
331
0
    return 0;
332
0
}
333
334
static long
335
current_RamSize(i_ctx_t *i_ctx_p)
336
2.37M
{
337
2.37M
    return i_ctx_p->system_params.RamSize;
338
2.37M
}
339
340
static long
341
current_JobTimeout(i_ctx_t *i_ctx_p)
342
0
{
343
0
    return i_ctx_p->system_params.JobTimeout;
344
0
}
345
346
static int
347
set_JobTimeout(i_ctx_t *i_ctx_p, long val)
348
0
{
349
0
    i_ctx_p->system_params.JobTimeout = val;
350
0
    return 0;
351
0
}
352
353
static long
354
current_WaitTimeout(i_ctx_t *i_ctx_p)
355
0
{
356
0
    return i_ctx_p->system_params.WaitTimeout;
357
0
}
358
359
static int
360
set_WaitTimeout(i_ctx_t *i_ctx_p, long val)
361
0
{
362
0
    i_ctx_p->system_params.WaitTimeout = val;
363
0
    return 0;
364
0
}
365
366
/* we duplicate this definition here instead of including bfont.h and
367
   all its dependencies */
368
369
13.5M
#define ifont_dir (gs_lib_ctx_get_interp_instance(imemory)->font_dir)
370
371
static long
372
current_MaxFontCache(i_ctx_t *i_ctx_p)
373
7.13M
{
374
7.13M
    return gs_currentcachesize(ifont_dir);
375
7.13M
}
376
static int
377
set_MaxFontCache(i_ctx_t *i_ctx_p, long val)
378
0
{
379
    /* Changing the cache params clears the "pairs" cache, which
380
       causes a crash if the in use font/matrix pair disappears
381
       during a text operation. So don't allow that to happen.
382
     */
383
0
    if (op_show_find(i_ctx_p) != NULL)
384
0
        return_error(gs_error_invalidaccess);
385
0
    return gs_setcachesize(igs, ifont_dir,
386
0
                           (uint)(val < 0 ? 0 : val > max_uint ? max_uint :
387
0
                                   val));
388
0
}
389
static long
390
current_CurFontCache(i_ctx_t *i_ctx_p)
391
2.37M
{
392
2.37M
    uint cstat[7];
393
394
2.37M
    gs_cachestatus(ifont_dir, cstat);
395
2.37M
    return cstat[0];
396
2.37M
}
397
398
/* Even though size_t is unsigned, PostScript limits this to signed range */
399
static size_t
400
current_MaxGlobalVM(i_ctx_t *i_ctx_p)
401
2.37M
{
402
2.37M
    gs_memory_gc_status_t stat;
403
2.37M
    size_t val;
404
405
2.37M
    gs_memory_gc_status(iimemory_global, &stat);
406
    /* RJW: This seems very supicious to me. I get that in CPSI
407
     * mode the max_vm figure needs to be kept to 32bit mode, but
408
     * surely clipping it should be correct, rather than truncating
409
     * it? i.e. min(stat.max_vm, 0x7fffffff) */
410
2.37M
    if (gs_currentcpsimode(imemory))
411
0
        return stat.max_vm & 0x7fffffff;
412
    /* else clamp at the maximum positive value for the size_t size signed integer */
413
2.37M
    val = min(stat.max_vm, MAX_VM_THRESHOLD);
414
2.37M
    return val;
415
2.37M
}
416
417
/* Even though size_t is unsigned, PostScript limits this to signed range */
418
static int
419
set_MaxGlobalVM(i_ctx_t *i_ctx_p, size_t val)
420
0
{
421
0
    gs_memory_gc_status_t stat;
422
423
0
    gs_memory_gc_status(iimemory_global, &stat);
424
0
    stat.max_vm = val;
425
0
    gs_memory_set_gc_status(iimemory_global, &stat);
426
0
    return 0;
427
0
}
428
static long
429
current_Revision(i_ctx_t *i_ctx_p)
430
2.37M
{
431
2.37M
    return gs_revision;
432
2.37M
}
433
434
static long
435
current_PageCount(i_ctx_t *i_ctx_p)
436
2.37M
{
437
2.37M
    gx_device *dev = gs_currentdevice(igs);
438
439
2.37M
    if ((*dev_proc(dev, get_page_device))(dev) != 0)
440
756k
        if (dev->ShowpageCount > i_ctx_p->nv_page_count)
441
51.6k
          i_ctx_p->nv_page_count = dev->ShowpageCount;
442
2.37M
    return 1000 + i_ctx_p->nv_page_count; /* Add 1000 to imitate NV memory */
443
2.37M
}
444
445
static const size_t_param_def_t system_size_t_params[] =
446
{
447
    /* Extensions */
448
    {"MaxGlobalVM", MIN_VM_THRESHOLD, MAX_VM_THRESHOLD, current_MaxGlobalVM, set_MaxGlobalVM}
449
};
450
451
static const long_param_def_t system_long_params[] =
452
{
453
    {"BuildTime", min_long, max_long, current_BuildTime, NULL},
454
    {"CurDisplayList", 0, MAX_UINT_PARAM, current_CurDisplayList, NULL},
455
    {"CurFormCache", 0, MAX_UINT_PARAM, current_CurFormCache, NULL},
456
    {"CurOutlineCache", 0, MAX_UINT_PARAM, current_CurOutlineCache, NULL},
457
    {"CurPatternCache", 0, MAX_UINT_PARAM, current_CurPatternCache, NULL},
458
    {"CurScreenStorage", 0, MAX_UINT_PARAM, current_CurScreenStorage, NULL},
459
    {"CurSourceList", 0, MAX_UINT_PARAM, current_CurSourceList, NULL},
460
    {"CurStoredScreenCache", 0, MAX_UINT_PARAM, current_CurStoredScreenCache, NULL},
461
    {"CurUPathCache", 0, MAX_UINT_PARAM, current_CurUPathCache, NULL},
462
    {"MaxDisplayAndSourceList", 0, MAX_UINT_PARAM, current_MaxDisplayAndSourceList, set_MaxDisplayAndSourceList},
463
    {"MaxDisplayList", 0, MAX_UINT_PARAM, current_MaxDisplayList, set_MaxDisplayList},
464
    {"MaxImageBuffer", 0, MAX_UINT_PARAM, current_MaxImageBuffer, set_MaxImageBuffer},
465
    {"MaxFormCache", 0, MAX_UINT_PARAM, current_MaxFormCache, set_MaxFormCache},
466
    {"MaxOutlineCache", 0, MAX_UINT_PARAM, current_MaxOutlineCache, set_MaxOutlineCache},
467
    {"MaxPatternCache", 0, MAX_UINT_PARAM, current_MaxPatternCache, set_MaxPatternCache},
468
    {"MaxUPathCache", 0, MAX_UINT_PARAM, current_MaxUPathCache, set_MaxUPathCache},
469
    {"MaxScreenStorage", 0, MAX_UINT_PARAM, current_MaxScreenStorage, set_MaxScreenStorage},
470
    {"MaxSourceList", 0, MAX_UINT_PARAM, current_MaxSourceList, set_MaxSourceList},
471
    {"RamSize", 0, MAX_UINT_PARAM, current_RamSize, NULL},
472
    {"MaxFontCache", 0, MAX_UINT_PARAM, current_MaxFontCache, set_MaxFontCache},
473
    {"CurFontCache", 0, MAX_UINT_PARAM, current_CurFontCache, NULL},
474
    {"JobTimeout", 0, MAX_UINT_PARAM, current_MaxFontCache, set_MaxFontCache},
475
    {"WaitTimeout", 0, MAX_UINT_PARAM, current_MaxFontCache, set_MaxFontCache},
476
    {"Revision", min_long, max_long, current_Revision, NULL},
477
    {"PageCount", min_long, max_long, current_PageCount, NULL}
478
};
479
480
/* Boolean values */
481
static bool
482
current_ByteOrder(i_ctx_t *i_ctx_p)
483
2.52M
{
484
2.52M
    return !ARCH_IS_BIG_ENDIAN;
485
2.52M
}
486
static const bool_param_def_t system_bool_params[] =
487
{
488
    {"ByteOrder", current_ByteOrder, NULL}
489
};
490
491
/* String values */
492
static void
493
current_RealFormat(i_ctx_t *i_ctx_p, gs_param_string * pval)
494
2.52M
{
495
2.52M
#if ARCH_FLOATS_ARE_IEEE
496
2.52M
    static const char *const rfs = "IEEE";
497
#else
498
    static const char *const rfs = "not IEEE";
499
#endif
500
501
2.52M
    pval->data = (const byte *)rfs;
502
2.52M
    pval->size = strlen(rfs);
503
2.52M
    pval->persistent = true;
504
2.52M
}
505
506
static void
507
current_LicenseID(i_ctx_t *i_ctx_p, gs_param_string * pval)
508
2.37M
{
509
2.37M
    static const char *const rfs = "LN-001";
510
511
2.37M
    pval->data = (const byte *)rfs;
512
2.37M
    pval->size = strlen(rfs);
513
2.37M
    pval->persistent = true;
514
2.37M
}
515
516
extern const char *const gs_product;
517
518
static void
519
current_PrinterName(i_ctx_t *i_ctx_p, gs_param_string * pval)
520
2.37M
{
521
2.37M
    pval->data = (const byte *)gs_product;
522
2.37M
    pval->size = strlen(gs_product);
523
2.37M
    pval->persistent = true;
524
2.37M
}
525
526
static void
527
current_InputDevice(i_ctx_t *i_ctx_p, gs_param_string * pval)
528
2.37M
{
529
2.37M
    pval->data = (const byte *)NULL;
530
2.37M
    pval->size = 0;
531
2.37M
    pval->persistent = true;
532
2.37M
}
533
534
static void
535
current_OutputDevice(i_ctx_t *i_ctx_p, gs_param_string * pval)
536
2.37M
{
537
2.37M
    pval->data = (const byte *)NULL;
538
2.37M
    pval->size = 0;
539
2.37M
    pval->persistent = true;
540
2.37M
}
541
542
static void
543
current_GenericResourceDir(i_ctx_t *i_ctx_p, gs_param_string * pval)
544
2.37M
{
545
2.37M
    ref *GRD_ref;
546
2.37M
    int code = 0;
547
548
2.37M
    pval->data = (const byte *)i_ctx_p->system_params.GenericResourceDir;
549
2.37M
    if (i_ctx_p->system_params.GenericResourceDir != NULL)
550
2.22M
        pval->size = strlen(i_ctx_p->system_params.GenericResourceDir);
551
147k
    else
552
147k
        pval->size = 0;
553
2.37M
    pval->persistent = false;
554
2.37M
}
555
556
static int
557
set_GenericResourceDir(i_ctx_t *i_ctx_p, gs_param_string *pval)
558
147k
{
559
147k
    if (gs_is_path_control_active(imemory))
560
0
        return 0;
561
562
147k
    if (i_ctx_p->system_params.GenericResourceDir != NULL){
563
0
        gs_free_object(imemory->non_gc_memory, i_ctx_p->system_params.GenericResourceDir, "set_GenericResourceDir");
564
0
    }
565
147k
    i_ctx_p->system_params.GenericResourceDir = (char *)gs_alloc_bytes(imemory->non_gc_memory, pval->size + 1, "set_GenericResourceDir");
566
147k
    if (i_ctx_p->system_params.GenericResourceDir == NULL)
567
0
        return_error(gs_error_VMerror);
568
147k
    memcpy(i_ctx_p->system_params.GenericResourceDir, pval->data, pval->size);
569
147k
    i_ctx_p->system_params.GenericResourceDir[pval->size] = 0x00;
570
147k
    return 0;
571
147k
};
572
573
static void
574
current_FontResourceDir(i_ctx_t *i_ctx_p, gs_param_string * pval)
575
2.50M
{
576
2.50M
    ref *GRD_ref;
577
2.50M
    int code = 0;
578
579
2.50M
    pval->data = (const byte *)i_ctx_p->system_params.FontResourceDir;
580
2.50M
    if (i_ctx_p->system_params.FontResourceDir != NULL)
581
2.35M
        pval->size = strlen(i_ctx_p->system_params.FontResourceDir);
582
147k
    else
583
147k
        pval->size = 0;
584
2.50M
    pval->persistent = false;
585
2.50M
}
586
587
static int
588
set_FontResourceDir(i_ctx_t *i_ctx_p, gs_param_string *pval)
589
147k
{
590
147k
    if (gs_is_path_control_active(imemory))
591
0
        return 0;
592
593
147k
    if (i_ctx_p->system_params.FontResourceDir != NULL){
594
0
        gs_free_object(imemory->non_gc_memory, i_ctx_p->system_params.FontResourceDir, "set_FontResourceDir");
595
0
    }
596
147k
    i_ctx_p->system_params.FontResourceDir = (char *)gs_alloc_bytes(imemory->non_gc_memory, pval->size + 1, "set_FontResourceDir");
597
147k
    if (i_ctx_p->system_params.FontResourceDir == NULL)
598
0
        return_error(gs_error_VMerror);
599
147k
    memcpy(i_ctx_p->system_params.FontResourceDir, pval->data, pval->size);
600
147k
    i_ctx_p->system_params.FontResourceDir[pval->size] = 0x00;
601
147k
    return 0;
602
147k
};
603
604
static void
605
current_GenericResourcePathSep(i_ctx_t *i_ctx_p, gs_param_string * pval)
606
3.72M
{
607
3.72M
    ref *GRD_ref;
608
3.72M
    int code = 0;
609
610
3.72M
    pval->data = (const byte *)i_ctx_p->system_params.GenericResourcePathSep;
611
3.72M
    if (i_ctx_p->system_params.GenericResourcePathSep != NULL)
612
3.57M
        pval->size = strlen(i_ctx_p->system_params.GenericResourcePathSep);
613
147k
    else
614
147k
        pval->size = 0;
615
3.72M
    pval->persistent = false;
616
3.72M
}
617
618
static int
619
set_GenericResourcePathSep(i_ctx_t *i_ctx_p, gs_param_string *pval)
620
147k
{
621
147k
    if (gs_is_path_control_active(imemory))
622
0
        return 0;
623
624
147k
    if (i_ctx_p->system_params.GenericResourcePathSep != NULL){
625
0
        gs_free_object(imemory->non_gc_memory, i_ctx_p->system_params.GenericResourcePathSep, "set_GenericResourcePathSep");
626
0
    }
627
147k
    i_ctx_p->system_params.GenericResourcePathSep = (char *)gs_alloc_bytes(imemory->non_gc_memory, pval->size + 1, "set_GenericResourcePathSep");
628
147k
    if (i_ctx_p->system_params.GenericResourcePathSep == NULL)
629
0
        return_error(gs_error_VMerror);
630
147k
    memcpy(i_ctx_p->system_params.GenericResourcePathSep, pval->data, pval->size);
631
147k
    i_ctx_p->system_params.GenericResourcePathSep[pval->size] = 0x00;
632
147k
    return 0;
633
147k
};
634
635
static void
636
current_PercentDiskFontResourceDir(i_ctx_t *i_ctx_p, gs_param_string * pval)
637
2.37M
{
638
2.37M
    ref *GRD_ref;
639
2.37M
    int code = 0;
640
641
2.37M
    pval->data = (const byte *)i_ctx_p->system_params.PercentDiskFontResourceDir;
642
2.37M
    if (i_ctx_p->system_params.PercentDiskFontResourceDir != NULL)
643
2.22M
        pval->size = strlen(i_ctx_p->system_params.PercentDiskFontResourceDir);
644
147k
    else
645
147k
        pval->size = 0;
646
2.37M
    pval->persistent = false;
647
2.37M
}
648
649
static int
650
set_PercentDiskFontResourceDir(i_ctx_t *i_ctx_p, gs_param_string *pval)
651
147k
{
652
147k
    if (gs_is_path_control_active(imemory))
653
0
        return 0;
654
655
147k
    if (i_ctx_p->system_params.PercentDiskFontResourceDir != NULL){
656
0
        gs_free_object(imemory->non_gc_memory, i_ctx_p->system_params.PercentDiskFontResourceDir, "set_PercentDiskFontResourceDir");
657
0
    }
658
147k
    i_ctx_p->system_params.PercentDiskFontResourceDir = (char *)gs_alloc_bytes(imemory->non_gc_memory, pval->size + 1, "set_PercentDiskFontResourceDir");
659
147k
    if (i_ctx_p->system_params.PercentDiskFontResourceDir == NULL)
660
0
        return_error(gs_error_VMerror);
661
147k
    memcpy(i_ctx_p->system_params.PercentDiskFontResourceDir, pval->data, pval->size);
662
147k
    i_ctx_p->system_params.PercentDiskFontResourceDir[pval->size] = 0x00;
663
147k
    return 0;
664
147k
};
665
666
static void
667
current_PercentDiskGenericResourceDir(i_ctx_t *i_ctx_p, gs_param_string * pval)
668
2.37M
{
669
2.37M
    ref *GRD_ref;
670
2.37M
    int code = 0;
671
672
2.37M
    pval->data = (const byte *)i_ctx_p->system_params.PercentDiskGenericResourceDir;
673
2.37M
    if (i_ctx_p->system_params.PercentDiskGenericResourceDir != NULL)
674
2.22M
        pval->size = strlen(i_ctx_p->system_params.PercentDiskGenericResourceDir);
675
147k
    else
676
147k
        pval->size = 0;
677
2.37M
    pval->persistent = false;
678
2.37M
}
679
680
static int
681
set_PercentDiskGenericResourceDir(i_ctx_t *i_ctx_p, gs_param_string *pval)
682
147k
{
683
147k
    if (gs_is_path_control_active(imemory))
684
0
        return 0;
685
686
147k
    if (i_ctx_p->system_params.PercentDiskGenericResourceDir != NULL){
687
0
        gs_free_object(imemory->non_gc_memory, i_ctx_p->system_params.PercentDiskGenericResourceDir, "set_PercentDiskGenericResourceDir");
688
0
    }
689
147k
    i_ctx_p->system_params.PercentDiskGenericResourceDir = (char *)gs_alloc_bytes(imemory->non_gc_memory, pval->size + 1, "set_PercentDiskGenericResourceDir");
690
147k
    if (i_ctx_p->system_params.PercentDiskGenericResourceDir == NULL)
691
0
        return_error(gs_error_VMerror);
692
147k
    memcpy(i_ctx_p->system_params.PercentDiskGenericResourceDir, pval->data, pval->size);
693
147k
    i_ctx_p->system_params.PercentDiskGenericResourceDir[pval->size] = 0x00;
694
147k
    return 0;
695
147k
};
696
697
static int
698
set_StartJobPassword(i_ctx_t *i_ctx_p, gs_param_string *pval)
699
0
{
700
0
    if (i_ctx_p->system_params.StartJobPassword != NULL){
701
0
        gs_free_object(imemory->non_gc_memory, i_ctx_p->system_params.StartJobPassword, "set_StartJobPassword");
702
0
    }
703
0
    i_ctx_p->system_params.StartJobPassword = (char *)gs_alloc_bytes(imemory->non_gc_memory, pval->size + 1, "set_StartJobPassword");
704
0
    if (i_ctx_p->system_params.StartJobPassword == NULL)
705
0
        return_error(gs_error_VMerror);
706
0
    memcpy(i_ctx_p->system_params.StartJobPassword, pval->data, pval->size);
707
0
    i_ctx_p->system_params.StartJobPassword[pval->size] = 0x00;
708
0
    return 0;
709
0
};
710
711
static int
712
set_SystemParamsPassword(i_ctx_t *i_ctx_p, gs_param_string *pval)
713
0
{
714
0
    if (i_ctx_p->system_params.SystemParamsPassword != NULL){
715
0
        gs_free_object(imemory->non_gc_memory, i_ctx_p->system_params.PercentDiskGenericResourceDir, "set_SystemParamsPassword");
716
0
    }
717
0
    i_ctx_p->system_params.SystemParamsPassword = (char *)gs_alloc_bytes(imemory->non_gc_memory, pval->size + 1, "set_SystemParamsPassword");
718
0
    if (i_ctx_p->system_params.SystemParamsPassword == NULL)
719
0
        return_error(gs_error_VMerror);
720
0
    memcpy(i_ctx_p->system_params.SystemParamsPassword, pval->data, pval->size);
721
0
    i_ctx_p->system_params.SystemParamsPassword[pval->size] = 0x00;
722
0
    return 0;
723
0
};
724
725
static const string_param_def_t system_string_params[] =
726
{
727
    {"RealFormat", current_RealFormat, NULL},
728
    {"LicenseID", current_LicenseID, NULL},
729
    {"PrinterName", current_PrinterName, NULL},
730
    {"CurInputDevice", current_InputDevice, NULL},
731
    {"CurOutputDevice", current_OutputDevice, NULL},
732
    {"GenericResourceDir", current_GenericResourceDir, set_GenericResourceDir},
733
    {"FontResourceDir", current_FontResourceDir, set_FontResourceDir},
734
    {"GenericResourcePathSep", current_GenericResourcePathSep, set_GenericResourcePathSep},
735
    {"%diskFontResourceDir", current_PercentDiskFontResourceDir, set_PercentDiskFontResourceDir},
736
    {"%diskGenericResourceDir", current_PercentDiskGenericResourceDir, set_PercentDiskGenericResourceDir},
737
    {"StartJobPassword", NULL, set_StartJobPassword},
738
    {"SystemParamsPassword", NULL, set_SystemParamsPassword},
739
};
740
741
/* The system parameter set */
742
static const param_set system_param_set =
743
{
744
    system_size_t_params, countof(system_size_t_params),
745
    NULL, 0,  /* No i64 params for systemparams (yet) */
746
    system_long_params, countof(system_long_params),
747
    system_bool_params, countof(system_bool_params),
748
    system_string_params, countof(system_string_params)
749
};
750
751
/* <dict> .setsystemparams - */
752
static int
753
zsetsystemparams(i_ctx_t *i_ctx_p)
754
147k
{
755
147k
    os_ptr op = osp;
756
147k
    int code;
757
147k
    dict_param_list list;
758
147k
    gs_param_list *const plist = (gs_param_list *)&list;
759
147k
    password pass;
760
761
147k
    check_op(1);
762
147k
    check_type(*op, t_dictionary);
763
147k
    code = dict_param_list_read(&list, op, NULL, false, iimemory);
764
147k
    if (code < 0)
765
0
        return code;
766
147k
    if (i_ctx_p->system_params.SystemParamsPassword != NULL && strlen(i_ctx_p->system_params.SystemParamsPassword) < 64) {
767
0
        memcpy(pass.data, i_ctx_p->system_params.SystemParamsPassword, strlen(i_ctx_p->system_params.SystemParamsPassword));;
768
0
        pass.size = strlen(i_ctx_p->system_params.SystemParamsPassword);
769
147k
    } else {
770
147k
        pass.data[0] = 0x00;
771
147k
        pass.size = 0;
772
147k
    }
773
147k
    code = param_check_password(plist, &pass);
774
147k
    if (code != 0) {
775
0
        if (code > 0)
776
0
            code = gs_note_error(gs_error_invalidaccess);
777
0
        goto out;
778
0
    }
779
780
147k
    code = setparams(i_ctx_p, plist, &system_param_set);
781
147k
  out:
782
147k
    iparam_list_release(&list);
783
147k
    if (code < 0)
784
0
        return code;
785
147k
    pop(1);
786
147k
    return 0;
787
147k
}
788
789
/* - .currentsystemparams <name1> <value1> ... */
790
static int
791
zcurrentsystemparams(i_ctx_t *i_ctx_p)
792
2.37M
{
793
2.37M
    return currentparams(i_ctx_p, &system_param_set);
794
2.37M
}
795
796
/* <name> .getsystemparam <value> */
797
static int
798
zgetsystemparam(i_ctx_t *i_ctx_p)
799
1.76M
{
800
1.76M
    return currentparam1(i_ctx_p, &system_param_set);
801
1.76M
}
802
803
/* ------ User parameters ------ */
804
805
/* Integer values */
806
static long
807
current_user_JobTimeout(i_ctx_t *i_ctx_p)
808
294k
{
809
294k
    return 0;
810
294k
}
811
static int
812
set_user_JobTimeout(i_ctx_t *i_ctx_p, long val)
813
631k
{
814
631k
    return 0;
815
631k
}
816
static long
817
current_MaxFontItem(i_ctx_t *i_ctx_p)
818
294k
{
819
294k
    return gs_currentcacheupper(ifont_dir);
820
294k
}
821
static int
822
set_MaxFontItem(i_ctx_t *i_ctx_p, long val)
823
778k
{
824
778k
    return gs_setcacheupper(ifont_dir, val);
825
778k
}
826
static long
827
current_MinFontCompress(i_ctx_t *i_ctx_p)
828
294k
{
829
294k
    return gs_currentcachelower(ifont_dir);
830
294k
}
831
static int
832
set_MinFontCompress(i_ctx_t *i_ctx_p, long val)
833
778k
{
834
778k
    return gs_setcachelower(ifont_dir, val);
835
778k
}
836
static long
837
current_MaxOpStack(i_ctx_t *i_ctx_p)
838
294k
{
839
294k
    return ref_stack_max_count(&o_stack);
840
294k
}
841
static int
842
set_MaxOpStack(i_ctx_t *i_ctx_p, long val)
843
778k
{
844
778k
    return ref_stack_set_max_count(&o_stack, val);
845
778k
}
846
static long
847
current_MaxDictStack(i_ctx_t *i_ctx_p)
848
294k
{
849
294k
    return ref_stack_max_count(&d_stack);
850
294k
}
851
static int
852
set_MaxDictStack(i_ctx_t *i_ctx_p, long val)
853
778k
{
854
778k
    return ref_stack_set_max_count(&d_stack, val);
855
778k
}
856
static long
857
current_MaxExecStack(i_ctx_t *i_ctx_p)
858
294k
{
859
294k
    return ref_stack_max_count(&e_stack);
860
294k
}
861
static int
862
set_MaxExecStack(i_ctx_t *i_ctx_p, long val)
863
778k
{
864
778k
    return ref_stack_set_max_count(&e_stack, val);
865
778k
}
866
static size_t
867
current_MaxLocalVM(i_ctx_t *i_ctx_p)
868
294k
{
869
294k
    gs_memory_gc_status_t stat;
870
294k
    size_t val;
871
872
294k
    gs_memory_gc_status(iimemory_local, &stat);
873
    /* RJW: This seems very supicious to me. I get that in CPSI
874
     * mode the max_vm figure needs to be kept to 32bit mode, but
875
     * surely clipping it should be correct, rather than truncating
876
     * it? i.e. min(stat.max_vm, 0x7fffffff) */
877
294k
    if (gs_currentcpsimode(imemory))
878
0
        return stat.max_vm & 0x7fffffff;
879
    /* else clamp at the maximun positive value for the size_t size signed integer */
880
294k
    val = min(stat.max_vm, MAX_VM_THRESHOLD);
881
294k
    return val;
882
294k
}
883
/* Even though size_t is unsigned, PostScript limits this to signed range */
884
static int
885
set_MaxLocalVM(i_ctx_t *i_ctx_p, size_t val)
886
631k
{
887
631k
    gs_memory_gc_status_t stat;
888
889
631k
    gs_memory_gc_status(iimemory_local, &stat);
890
631k
    stat.max_vm = val;
891
631k
    gs_memory_set_gc_status(iimemory_local, &stat);
892
631k
    return 0;
893
631k
}
894
static long
895
current_VMReclaim(i_ctx_t *i_ctx_p)
896
294k
{
897
294k
    gs_memory_gc_status_t gstat, lstat;
898
899
294k
    gs_memory_gc_status(iimemory_global, &gstat);
900
294k
    gs_memory_gc_status(iimemory_local, &lstat);
901
294k
    return (!gstat.enabled ? -2 : !lstat.enabled ? -1 : 0);
902
294k
}
903
static int64_t
904
current_VMThreshold(i_ctx_t *i_ctx_p)
905
294k
{
906
294k
    gs_memory_gc_status_t stat;
907
908
294k
    gs_memory_gc_status(iimemory_local, &stat);
909
294k
    return stat.vm_threshold;
910
294k
}
911
static long
912
current_user_WaitTimeout(i_ctx_t *i_ctx_p)
913
294k
{
914
294k
    return 0;
915
294k
}
916
static int
917
set_user_WaitTimeout(i_ctx_t *i_ctx_p, long val)
918
631k
{
919
631k
    return 0;
920
631k
}
921
static long
922
current_MinScreenLevels(i_ctx_t *i_ctx_p)
923
294k
{
924
294k
    return gs_currentminscreenlevels(imemory);
925
294k
}
926
static int
927
set_MinScreenLevels(i_ctx_t *i_ctx_p, long val)
928
631k
{
929
631k
    gs_setminscreenlevels(imemory, (uint) val);
930
631k
    return 0;
931
631k
}
932
static long
933
current_AlignToPixels(i_ctx_t *i_ctx_p)
934
294k
{
935
294k
    return gs_currentaligntopixels(ifont_dir);
936
294k
}
937
static int
938
set_AlignToPixels(i_ctx_t *i_ctx_p, long val)
939
631k
{
940
631k
    gs_setaligntopixels(ifont_dir, (uint)val);
941
631k
    return 0;
942
631k
}
943
static long
944
current_GridFitTT(i_ctx_t *i_ctx_p)
945
294k
{
946
294k
    return gs_currentgridfittt(ifont_dir);
947
294k
}
948
static int
949
set_GridFitTT(i_ctx_t *i_ctx_p, long val)
950
631k
{
951
631k
    gs_setgridfittt(ifont_dir, (uint)val);
952
631k
    return 0;
953
631k
}
954
955
#undef ifont_dir
956
957
static long
958
current_MaxFormItem(i_ctx_t *i_ctx_p)
959
294k
{
960
294k
    return(i_ctx_p->user_params.MaxFormItem);
961
294k
}
962
static int
963
set_MaxFormItem(i_ctx_t *i_ctx_p, long val)
964
631k
{
965
631k
    i_ctx_p->user_params.MaxFormItem = val;
966
631k
    return 0;
967
631k
}
968
969
static long
970
current_MaxPatternItem(i_ctx_t *i_ctx_p)
971
294k
{
972
294k
    return(i_ctx_p->user_params.MaxPatternItem);
973
294k
}
974
static int
975
set_MaxPatternItem(i_ctx_t *i_ctx_p, long val)
976
631k
{
977
631k
    i_ctx_p->user_params.MaxPatternItem = val;
978
631k
    return 0;
979
631k
}
980
981
static long
982
current_MaxScreenItem(i_ctx_t *i_ctx_p)
983
294k
{
984
294k
    return(i_ctx_p->user_params.MaxScreenItem);
985
294k
}
986
static int
987
set_MaxScreenItem(i_ctx_t *i_ctx_p, long val)
988
631k
{
989
631k
    i_ctx_p->user_params.MaxScreenItem = val;
990
631k
    return 0;
991
631k
}
992
993
static long
994
current_MaxUPathItem(i_ctx_t *i_ctx_p)
995
294k
{
996
294k
    return(i_ctx_p->user_params.MaxUPathItem);
997
294k
}
998
static int
999
set_MaxUPathItem(i_ctx_t *i_ctx_p, long val)
1000
631k
{
1001
631k
    i_ctx_p->user_params.MaxUPathItem = val;
1002
631k
    return 0;
1003
631k
}
1004
1005
static long
1006
current_MaxSuperScreen(i_ctx_t *i_ctx_p)
1007
294k
{
1008
294k
    return(i_ctx_p->user_params.MaxFormItem);
1009
294k
}
1010
static int
1011
set_MaxSuperScreen(i_ctx_t *i_ctx_p, long val)
1012
778k
{
1013
778k
    i_ctx_p->user_params.MaxFormItem = val;
1014
778k
    return 0;
1015
778k
}
1016
1017
static long
1018
current_HalftoneMode(i_ctx_t *i_ctx_p)
1019
294k
{
1020
294k
    return(i_ctx_p->user_params.HalftoneMode);
1021
294k
}
1022
static int
1023
set_HalftoneMode(i_ctx_t *i_ctx_p, long val)
1024
778k
{
1025
778k
    i_ctx_p->user_params.HalftoneMode = val;
1026
778k
    return 0;
1027
778k
}
1028
1029
static void
1030
current_devicen_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1031
294k
{
1032
294k
    gs_currentdevicenicc(igs, pval);
1033
294k
}
1034
1035
static int
1036
set_devicen_profile_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1037
631k
{
1038
631k
    return gs_setdevicenprofileicc(igs, pval);
1039
631k
}
1040
1041
static void
1042
current_default_gray_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1043
294k
{
1044
294k
    gs_currentdefaultgrayicc(igs, pval);
1045
294k
}
1046
1047
static int
1048
set_default_gray_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1049
632k
{
1050
632k
    return gs_setdefaultgrayicc(igs, pval);
1051
632k
}
1052
1053
static void
1054
current_icc_directory(i_ctx_t *i_ctx_p, gs_param_string * pval)
1055
294k
{
1056
294k
    gs_currenticcdirectory(igs, pval);
1057
294k
}
1058
1059
static int
1060
set_icc_directory(i_ctx_t *i_ctx_p, gs_param_string * pval)
1061
631k
{
1062
631k
    return gs_seticcdirectory(igs, pval);
1063
631k
}
1064
1065
static void
1066
current_srcgtag_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1067
294k
{
1068
294k
    gs_currentsrcgtagicc(igs, pval);
1069
294k
}
1070
1071
static int
1072
set_srcgtag_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1073
631k
{
1074
631k
    return gs_setsrcgtagicc(igs, pval);
1075
631k
}
1076
1077
static void
1078
current_default_rgb_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1079
294k
{
1080
294k
    gs_currentdefaultrgbicc(igs, pval);
1081
294k
}
1082
1083
static int
1084
set_default_rgb_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1085
633k
{
1086
633k
    return gs_setdefaultrgbicc(igs, pval);
1087
633k
}
1088
1089
static void
1090
current_named_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1091
294k
{
1092
294k
    gs_currentnamedicc(igs, pval);
1093
294k
}
1094
1095
static int
1096
set_named_profile_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1097
631k
{
1098
631k
    return gs_setnamedprofileicc(igs, pval);
1099
631k
}
1100
1101
static void
1102
current_default_cmyk_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1103
294k
{
1104
294k
    gs_currentdefaultcmykicc(igs, pval);
1105
294k
}
1106
1107
static int
1108
set_default_cmyk_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1109
631k
{
1110
631k
    return gs_setdefaultcmykicc(igs, pval);
1111
631k
}
1112
1113
static void
1114
current_lab_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1115
294k
{
1116
294k
    gs_currentlabicc(igs, pval);
1117
294k
}
1118
1119
static int
1120
set_lab_icc(i_ctx_t *i_ctx_p, gs_param_string * pval)
1121
631k
{
1122
631k
    return gs_setlabicc(igs, pval);
1123
631k
}
1124
1125
static void
1126
current_JobName(i_ctx_t *i_ctx_p, gs_param_string * pval)
1127
294k
{
1128
294k
    if (i_ctx_p->user_params.JobName == NULL) {
1129
147k
        pval->data = NULL;
1130
147k
        pval->size = 0;
1131
147k
        pval->persistent = false;
1132
147k
    } else {
1133
146k
        pval->data = (const byte *)i_ctx_p->user_params.JobName;
1134
146k
        pval->size = strlen(i_ctx_p->user_params.JobName);
1135
146k
        pval->persistent = false;
1136
146k
    }
1137
294k
}
1138
1139
static int
1140
set_JobName(i_ctx_t *i_ctx_p, gs_param_string * pval)
1141
778k
{
1142
778k
    if (i_ctx_p->user_params.JobName != NULL) {
1143
631k
        gs_free_object(imemory->non_gc_memory, i_ctx_p->user_params.JobName, "set_JobName");
1144
631k
    }
1145
778k
    i_ctx_p->user_params.JobName = (char *)gs_alloc_bytes(imemory->non_gc_memory, pval->size + 1, "set_JobName");
1146
778k
    if (i_ctx_p->user_params.JobName == NULL)
1147
0
        return_error(gs_error_VMerror);
1148
778k
    memcpy(i_ctx_p->user_params.JobName, pval->data, pval->size);
1149
778k
    i_ctx_p->user_params.JobName[pval->size] = 0x00;
1150
778k
    return 0;
1151
778k
}
1152
1153
static const size_t_param_def_t user_size_t_params[] =
1154
{
1155
    {"MaxLocalVM", MIN_VM_THRESHOLD, MAX_VM_THRESHOLD, current_MaxLocalVM, set_MaxLocalVM}
1156
};
1157
1158
static const i64_param_def_t user_i64_params[] =
1159
{
1160
    {"VMThreshold", -1, MAX_VM_THRESHOLD, current_VMThreshold, set_vm_threshold},
1161
};
1162
1163
static const long_param_def_t user_long_params[] =
1164
{
1165
    {"JobTimeout", 0, MAX_UINT_PARAM,
1166
     current_user_JobTimeout, set_user_JobTimeout},
1167
    {"MaxFontItem", MIN_INT_PARAM, MAX_UINT_PARAM,
1168
     current_MaxFontItem, set_MaxFontItem},
1169
    {"MinFontCompress", MIN_INT_PARAM, MAX_UINT_PARAM,
1170
     current_MinFontCompress, set_MinFontCompress},
1171
    {"MaxOpStack", -1, max_long,
1172
     current_MaxOpStack, set_MaxOpStack},
1173
    {"MaxDictStack", -1, max_long,
1174
     current_MaxDictStack, set_MaxDictStack},
1175
    {"MaxExecStack", -1, max_long,
1176
     current_MaxExecStack, set_MaxExecStack},
1177
    {"VMReclaim", -2, 0,
1178
     current_VMReclaim, set_vm_reclaim},
1179
    {"WaitTimeout", 0, MAX_UINT_PARAM,
1180
     current_user_WaitTimeout, set_user_WaitTimeout},
1181
    /* Extensions */
1182
    {"MinScreenLevels", 0, MAX_UINT_PARAM,
1183
     current_MinScreenLevels, set_MinScreenLevels},
1184
    {"AlignToPixels", 0, 1,
1185
     current_AlignToPixels, set_AlignToPixels},
1186
    {"GridFitTT", 0, 3,
1187
     current_GridFitTT, set_GridFitTT},
1188
    {"MaxFormItem", 0, MAX_UINT_PARAM,
1189
    current_MaxFormItem, set_MaxFormItem},
1190
    {"MaxPatternItem", 0, MAX_UINT_PARAM,
1191
    current_MaxPatternItem, set_MaxPatternItem},
1192
    {"MaxScreenItem", 0, MAX_UINT_PARAM,
1193
    current_MaxScreenItem, set_MaxScreenItem},
1194
    {"MaxUPathItem", 0, MAX_UINT_PARAM,
1195
    current_MaxUPathItem, set_MaxUPathItem},
1196
    {"HalftoneMode", 0, 2,
1197
    current_HalftoneMode, set_HalftoneMode},
1198
    {"MaxSuperScreen", 0, MAX_UINT_PARAM,
1199
    current_MaxSuperScreen, set_MaxSuperScreen},
1200
};
1201
1202
/* Note that string objects that are maintained as user params must be
1203
   either allocated in non-gc memory or be a constant in the executable.
1204
   The problem stems from the way userparams are retained during garbage
1205
   collection in a param_list (collected by currentuserparams).  For
1206
   some reason this param_list does not get the pointers to strings relocated
1207
   during the GC. Note that the param_dict itself is correctly updated by reloc,
1208
   it is just the pointers to the strings in the param_list that are not traced
1209
   and updated. An example of this includes the ICCProfilesDir, which sets a
1210
   string in the icc_manager. When a reclaim occurs, the string is relocated
1211
   (when in non-gc memory and when it is noted to the gc with the proper object
1212
   descriptor).  Then if a set_icc_directory occurs, the user params pointer has
1213
   NOT been updated and validation problems will occur. */
1214
static const string_param_def_t user_string_params[] =
1215
{
1216
    {"DefaultGrayProfile", current_default_gray_icc, set_default_gray_icc},
1217
    {"DefaultRGBProfile", current_default_rgb_icc, set_default_rgb_icc},
1218
    {"DefaultCMYKProfile", current_default_cmyk_icc, set_default_cmyk_icc},
1219
    {"NamedProfile", current_named_icc, set_named_profile_icc},
1220
    {"ICCProfilesDir", current_icc_directory, set_icc_directory},
1221
    {"LabProfile", current_lab_icc, set_lab_icc},
1222
    {"DeviceNProfile", current_devicen_icc, set_devicen_profile_icc},
1223
    {"SourceObjectICC", current_srcgtag_icc, set_srcgtag_icc},
1224
    {"JobName", current_JobName, set_JobName},
1225
};
1226
1227
/* Boolean values */
1228
static bool
1229
current_AccurateScreens(i_ctx_t *i_ctx_p)
1230
294k
{
1231
294k
    return gs_currentaccuratescreens(imemory);
1232
294k
}
1233
static int
1234
set_AccurateScreens(i_ctx_t *i_ctx_p, bool val)
1235
631k
{
1236
631k
    gs_setaccuratescreens(imemory, val);
1237
631k
    return 0;
1238
631k
}
1239
/* Boolean values */
1240
static bool
1241
current_OverrideICC(i_ctx_t *i_ctx_p)
1242
294k
{
1243
294k
    return gs_currentoverrideicc(igs);
1244
294k
}
1245
static int
1246
set_OverrideICC(i_ctx_t *i_ctx_p, bool val)
1247
631k
{
1248
631k
    gs_setoverrideicc(igs, val);
1249
631k
    return 0;
1250
631k
}
1251
static bool
1252
current_LockFilePermissions(i_ctx_t *i_ctx_p)
1253
294k
{
1254
294k
    return i_ctx_p->LockFilePermissions;
1255
294k
}
1256
static int
1257
set_LockFilePermissions(i_ctx_t *i_ctx_p, bool val)
1258
631k
{
1259
    /* allow locking even if already locked */
1260
631k
    if (i_ctx_p->LockFilePermissions && !val)
1261
0
        return_error(gs_error_invalidaccess);
1262
631k
    i_ctx_p->LockFilePermissions = val;
1263
631k
    return 0;
1264
631k
}
1265
static bool
1266
current_RenderTTNotdef(i_ctx_t *i_ctx_p)
1267
294k
{
1268
294k
    return i_ctx_p->RenderTTNotdef;
1269
294k
}
1270
static int
1271
set_RenderTTNotdef(i_ctx_t *i_ctx_p, bool val)
1272
631k
{
1273
631k
    i_ctx_p->RenderTTNotdef = val;
1274
631k
    return 0;
1275
631k
}
1276
1277
static const bool_param_def_t user_bool_params[] =
1278
{
1279
    {"AccurateScreens", current_AccurateScreens, set_AccurateScreens},
1280
    {"LockFilePermissions", current_LockFilePermissions, set_LockFilePermissions},
1281
    {"RenderTTNotdef", current_RenderTTNotdef, set_RenderTTNotdef},
1282
    {"OverrideICC", current_OverrideICC, set_OverrideICC},
1283
};
1284
1285
/* The user parameter set */
1286
static const param_set user_param_set =
1287
{
1288
    user_size_t_params, countof(user_size_t_params),
1289
    user_i64_params, countof(user_i64_params),
1290
    user_long_params, countof(user_long_params),
1291
    user_bool_params, countof(user_bool_params),
1292
    user_string_params, countof(user_string_params)
1293
};
1294
1295
/* <dict> .setuserparams - */
1296
/* We break this out for use when switching contexts. */
1297
int
1298
set_user_params(i_ctx_t *i_ctx_p, const ref *paramdict)
1299
3.28M
{
1300
3.28M
    dict_param_list list;
1301
3.28M
    int code, i;
1302
1303
3.28M
    check_type(*paramdict, t_dictionary);
1304
3.28M
    code = dict_param_list_read(&list, paramdict, NULL, false, iimemory);
1305
3.28M
    if (code < 0)
1306
0
        return code;
1307
3.28M
    code = setparams(i_ctx_p, (gs_param_list *)&list, &user_param_set);
1308
3.28M
    iparam_list_release(&list);
1309
3.28M
    if (code < 0)
1310
10
        return code;
1311
1312
3.28M
    {
1313
3.28M
        int index, code;
1314
3.28M
        ref elt[2], *userparams_dict;
1315
1316
3.28M
        if (dict_find_string(systemdict, "userparams", &userparams_dict) < 0)
1317
0
            return 0;
1318
1319
3.28M
        index = dict_first(paramdict);
1320
28.1M
        while ((index = dict_next(paramdict, index, elt)) >= 0)
1321
24.9M
        {
1322
24.9M
            if (r_has_type(&elt[0], t_name)) {
1323
24.9M
                ref sref;
1324
1325
24.9M
                name_string_ref(imemory, (const ref *)&elt[0], &sref);
1326
24.9M
                if (r_is_number(&elt[1])) {
1327
26.0M
                    for (i = 0;i < countof(user_size_t_params);i++) {
1328
13.3M
                        if (strlen(user_size_t_params[i].pname) == r_size(&sref) && strncmp((const char *)sref.value.bytes, user_size_t_params[i].pname, r_size(&sref)) == 0) {
1329
631k
                            code = dict_put(userparams_dict, &elt[0], &elt[1], &idict_stack);
1330
631k
                            if (code < 0)
1331
0
                                return code;
1332
631k
                            break;
1333
631k
                        }
1334
13.3M
                    }
1335
25.8M
                    for (i = 0;i < countof(user_i64_params);i++) {
1336
13.3M
                        if (strlen(user_i64_params[i].pname) == r_size(&sref) && strncmp((const char *)sref.value.bytes, user_i64_params[i].pname, r_size(&sref)) == 0) {
1337
                            /* We only have one i64 parameter 'VMThreshold', and it needs special cas treatment. If we ever have more we'll
1338
                             * need to isolate it. If VMThreshold is '-1' then it takes a default value, which is hadnled by set_vmthreshold.
1339
                             * What we need to do is set the value of the PostScript object to be the value actually in use.
1340
                             */
1341
778k
                            gs_memory_gc_status_t stat;
1342
1343
778k
                            gs_memory_gc_status(iimemory_local, &stat);
1344
778k
                            if (r_has_type(&elt[1], t_integer))
1345
778k
                                    elt[1].value.intval = (int)stat.vm_threshold;
1346
778k
                            if (r_has_type(&elt[1], t_real))
1347
0
                                    elt[1].value.realval = (float)stat.vm_threshold;
1348
778k
                            code = dict_put(userparams_dict, &elt[0], &elt[1], &idict_stack);
1349
778k
                            if (code < 0)
1350
0
                                return code;
1351
778k
                            break;
1352
778k
                        }
1353
13.3M
                    }
1354
130M
                    for (i = 0;i < countof(user_long_params);i++) {
1355
129M
                        if (strlen(user_long_params[i].pname) == r_size(&sref) && strncmp((const char *)sref.value.bytes, user_long_params[i].pname, r_size(&sref)) == 0) {
1356
11.9M
                            code = dict_put(userparams_dict, &elt[0], &elt[1], &idict_stack);
1357
11.9M
                            if (code < 0)
1358
0
                                return code;
1359
11.9M
                            break;
1360
11.9M
                        }
1361
129M
                    }
1362
13.3M
                }
1363
24.9M
                if (r_has_type(&elt[1], t_boolean)) {
1364
13.1M
                    for (i = 0;i < countof(user_bool_params);i++) {
1365
11.7M
                        if (strlen(user_bool_params[i].pname) == r_size(&sref) && strncmp((const char *)sref.value.bytes, user_bool_params[i].pname, r_size(&sref)) == 0) {
1366
2.52M
                            code = dict_put(userparams_dict, &elt[0], &elt[1], &idict_stack);
1367
2.52M
                            if (code < 0)
1368
0
                                return code;
1369
2.52M
                            break;
1370
2.52M
                        }
1371
11.7M
                    }
1372
3.89M
                }
1373
24.9M
                if (r_has_type(&elt[1], t_string)) {
1374
29.7M
                    for (i = 0;i < countof(user_string_params);i++) {
1375
29.7M
                        if (strlen(user_string_params[i].pname) == r_size(&sref) && strncmp((const char *)sref.value.bytes, user_string_params[i].pname, r_size(&sref)) == 0) {
1376
5.83M
                            code = dict_put(userparams_dict, &elt[0], &elt[1], &idict_stack);
1377
5.83M
                            if (code < 0)
1378
0
                                return code;
1379
5.83M
                            break;
1380
5.83M
                        }
1381
29.7M
                    }
1382
5.83M
                }
1383
24.9M
                if (strncmp((const char *)sref.value.bytes, "ProcessDSCComment", r_size(&sref)) == 0) {
1384
1.07M
                    if (!r_has_type(&elt[1], t_null) && !r_is_array(&elt[1]))
1385
0
                        return_error(gs_error_typecheck);
1386
1.07M
                    code = dict_put(userparams_dict, &elt[0], &elt[1], &idict_stack);
1387
1.07M
                    if (code < 0)
1388
0
                        return code;
1389
1.07M
                }
1390
24.9M
                if (strncmp((const char *)sref.value.bytes, "ProcessComment", r_size(&sref)) == 0) {
1391
631k
                    if (!r_has_type(&elt[1], t_null) && !r_is_array(&elt[1]))
1392
0
                        return_error(gs_error_typecheck);
1393
631k
                    code = dict_put(userparams_dict, &elt[0], &elt[1], &idict_stack);
1394
631k
                    if (code < 0)
1395
0
                        return code;
1396
631k
                }
1397
24.9M
                if (strncmp((const char *)sref.value.bytes, "IdiomRecognition", r_size(&sref)) == 0) {
1398
1.51M
                    if (!r_has_type(&elt[1], t_null) && !r_is_array(&elt[1]) && !r_has_type(&elt[1], t_boolean))
1399
0
                        return_error(gs_error_typecheck);
1400
1.51M
                    code = dict_put(userparams_dict, &elt[0], &elt[1], &idict_stack);
1401
1.51M
                    if (code < 0)
1402
0
                        return code;
1403
1.51M
                }
1404
24.9M
            }
1405
24.9M
        }
1406
3.28M
    }
1407
3.28M
    return code;
1408
3.28M
}
1409
static int
1410
zsetuserparams(i_ctx_t *i_ctx_p)
1411
2.83M
{
1412
2.83M
    os_ptr op = osp;
1413
2.83M
    int code;
1414
1415
2.83M
    check_op(1);
1416
2.83M
    code = set_user_params(i_ctx_p, op);
1417
2.83M
    if (code >= 0) {
1418
        /* Update cached scanner options. */
1419
2.83M
        i_ctx_p->scanner_options =
1420
2.83M
            ztoken_scanner_options(op, i_ctx_p->scanner_options);
1421
2.83M
        pop(1);
1422
2.83M
    }
1423
2.83M
    return code;
1424
2.83M
}
1425
1426
/* - .currentuserparams <name1> <value1> ... */
1427
static int
1428
zcurrentuserparams(i_ctx_t *i_ctx_p)
1429
294k
{
1430
294k
    return currentparams(i_ctx_p, &user_param_set);
1431
294k
}
1432
1433
/* <name> .getuserparam <value> */
1434
static int
1435
zgetuserparam(i_ctx_t *i_ctx_p)
1436
0
{
1437
0
    return currentparam1(i_ctx_p, &user_param_set);
1438
0
}
1439
1440
/* ------ Initialization procedure ------ */
1441
1442
const op_def zusparam_op_defs[] =
1443
{
1444
        /* User and system parameters are accessible even in Level 1 */
1445
        /* (if this is a Level 2 system). */
1446
    {"0.currentsystemparams", zcurrentsystemparams},
1447
    {"0.currentuserparams", zcurrentuserparams},
1448
    {"1.getsystemparam", zgetsystemparam},
1449
    {"1.getuserparam", zgetuserparam},
1450
    {"1.setsystemparams", zsetsystemparams},
1451
    {"1.setuserparams", zsetuserparams},
1452
        /* The rest of the operators are defined only in Level 2. */
1453
    op_def_begin_level2(),
1454
    {"1.checkpassword", zcheckpassword},
1455
    op_def_end(0)
1456
};
1457
1458
/* ------ Internal procedures ------ */
1459
1460
/* Set the values of a parameter set from a parameter list. */
1461
/* We don't attempt to back out if anything fails. */
1462
static int
1463
setparams(i_ctx_t *i_ctx_p, gs_param_list * plist, const param_set * pset)
1464
3.42M
{
1465
3.42M
    int code;
1466
3.42M
    unsigned int i;
1467
1468
6.85M
    for (i = 0; i < pset->size_t_count; i++) {
1469
3.42M
        const size_t_param_def_t *pdef = &pset->size_t_defs[i];
1470
3.42M
        size_t val;
1471
1472
3.42M
        if (pdef->set == NULL)
1473
0
            continue;
1474
3.42M
        code = param_read_size_t(plist, pdef->pname, &val);
1475
3.42M
        switch (code) {
1476
0
            default:    /* invalid */
1477
0
                return code;
1478
2.79M
            case 1:   /* missing */
1479
2.79M
                break;
1480
631k
            case 0:
1481
631k
                if (val < pdef->min_value || val > pdef->max_value)
1482
0
                    return_error(gs_error_rangecheck);
1483
631k
                code = (*pdef->set)(i_ctx_p, val);
1484
631k
                if (code < 0)
1485
0
                    return code;
1486
3.42M
        }
1487
3.42M
    }
1488
1489
6.70M
    for (i = 0; i < pset->i64_count; i++) {
1490
3.28M
        const i64_param_def_t *pdef = &pset->i64_defs[i];
1491
3.28M
        int64_t val;
1492
1493
3.28M
        if (pdef->set == NULL)
1494
0
            continue;
1495
3.28M
        code = param_read_i64(plist, pdef->pname, &val);
1496
3.28M
        switch (code) {
1497
0
            default:    /* invalid */
1498
0
                return code;
1499
2.50M
            case 1:   /* missing */
1500
2.50M
                break;
1501
778k
            case 0:
1502
778k
                if (val < pdef->min_value || val > pdef->max_value)
1503
0
                    return_error(gs_error_rangecheck);
1504
778k
                code = (*pdef->set)(i_ctx_p, val);
1505
778k
                if (code < 0)
1506
0
                    return code;
1507
3.28M
        }
1508
3.28M
    }
1509
1510
62.8M
    for (i = 0; i < pset->long_count; i++) {
1511
59.4M
        const long_param_def_t *pdef = &pset->long_defs[i];
1512
59.4M
        long val;
1513
1514
59.4M
        if (pdef->set == NULL)
1515
1.91M
            continue;
1516
57.5M
        code = param_read_long(plist, pdef->pname, &val);
1517
57.5M
        switch (code) {
1518
7
            default:    /* invalid */
1519
7
                return code;
1520
45.6M
            case 1:   /* missing */
1521
45.6M
                break;
1522
11.9M
            case 0:
1523
11.9M
                if (val < pdef->min_value || val > pdef->max_value)
1524
3
                    return_error(gs_error_rangecheck);
1525
11.9M
                code = (*pdef->set)(i_ctx_p, val);
1526
11.9M
                if (code < 0)
1527
0
                    return code;
1528
57.5M
        }
1529
57.5M
    }
1530
16.6M
    for (i = 0; i < pset->bool_count; i++) {
1531
13.2M
        const bool_param_def_t *pdef = &pset->bool_defs[i];
1532
13.2M
        bool val;
1533
1534
13.2M
        if (pdef->set == NULL)
1535
147k
            continue;
1536
13.1M
        code = param_read_bool(plist, pdef->pname, &val);
1537
13.1M
        if (code == 0)
1538
2.52M
            code = (*pdef->set)(i_ctx_p, val);
1539
13.1M
        if (code < 0)
1540
0
            return code;
1541
13.1M
    }
1542
1543
34.7M
    for (i = 0; i < pset->string_count; i++) {
1544
31.2M
        const string_param_def_t *pdef = &pset->string_defs[i];
1545
31.2M
        gs_param_string val;
1546
1547
31.2M
        if (pdef->set == NULL)
1548
736k
            continue;
1549
30.5M
        code = param_read_string(plist, pdef->pname, &val);
1550
30.5M
        switch (code) {
1551
0
            default:    /* invalid */
1552
0
                return code;
1553
23.9M
            case 1:   /* missing */
1554
23.9M
                break;
1555
6.57M
            case 0:
1556
6.57M
                code = (*pdef->set)(i_ctx_p, &val);
1557
6.57M
                if (code < 0)
1558
0
                    return code;
1559
30.5M
        }
1560
30.5M
    }
1561
1562
3.42M
    return 0;
1563
3.42M
}
1564
1565
/* Get the current values of a parameter set to the stack. */
1566
static bool
1567
pname_matches(const char *pname, const ref * psref)
1568
171M
{
1569
171M
    return
1570
171M
        (psref == 0 ||
1571
69.0M
         !bytes_compare((const byte *)pname, strlen(pname),
1572
69.0M
                        psref->value.const_bytes, r_size(psref)));
1573
171M
}
1574
static int
1575
current_param_list(i_ctx_t *i_ctx_p, const param_set * pset,
1576
                   const ref * psref /*t_string */ )
1577
4.44M
{
1578
4.44M
    stack_param_list list;
1579
4.44M
    gs_param_list *const plist = (gs_param_list *)&list;
1580
4.44M
    int code = 0;
1581
4.44M
    unsigned int i;
1582
1583
4.44M
    stack_param_list_write(&list, &o_stack, NULL, iimemory);
1584
1585
8.88M
    for (i = 0; i < pset->size_t_count; i++) {
1586
4.44M
        const char *pname = pset->size_t_defs[i].pname;
1587
1588
4.44M
        if (pname_matches(pname, psref)) {
1589
2.67M
            if (pset->size_t_defs[i].current != NULL) {
1590
2.67M
                size_t val = (*pset->size_t_defs[i].current)(i_ctx_p);
1591
1592
2.67M
                code = param_write_size_t(plist, pname, &val);
1593
2.67M
                if (code < 0)
1594
0
                    return code;
1595
2.67M
            }
1596
2.67M
        }
1597
4.44M
    }
1598
4.73M
    for (i = 0; i < pset->i64_count; i++) {
1599
294k
        const char *pname = pset->i64_defs[i].pname;
1600
1601
294k
        if (pname_matches(pname, psref)) {
1602
294k
            if (pset->i64_defs[i].current != NULL) {
1603
294k
                int64_t val = (*pset->i64_defs[i].current)(i_ctx_p);
1604
1605
294k
                code = param_write_i64(plist, pname, &val);
1606
294k
                if (code < 0)
1607
0
                    return code;
1608
294k
            }
1609
294k
        }
1610
294k
    }
1611
113M
    for (i = 0; i < pset->long_count; i++) {
1612
108M
        const char *pname = pset->long_defs[i].pname;
1613
1614
108M
        if (pname_matches(pname, psref)) {
1615
64.4M
            if (pset->long_defs[i].current != NULL) {
1616
64.4M
                long val = (*pset->long_defs[i].current)(i_ctx_p);
1617
1618
64.4M
                code = param_write_long(plist, pname, &val);
1619
64.4M
                if (code < 0)
1620
0
                    return code;
1621
64.4M
            }
1622
64.4M
        }
1623
108M
    }
1624
9.76M
    for (i = 0; i < pset->bool_count; i++) {
1625
5.32M
        const char *pname = pset->bool_defs[i].pname;
1626
1627
5.32M
        if (pname_matches(pname, psref)) {
1628
3.70M
            if (pset->bool_defs[i].current != NULL) {
1629
3.70M
                bool val = (*pset->bool_defs[i].current)(i_ctx_p);
1630
1631
3.70M
                code = param_write_bool(plist, pname, &val);
1632
3.70M
                if (code < 0)
1633
0
                    return code;
1634
3.70M
            }
1635
3.70M
        }
1636
5.32M
    }
1637
56.8M
    for (i = 0; i < pset->string_count; i++) {
1638
52.4M
        const char *pname = pset->string_defs[i].pname;
1639
1640
52.4M
        if (pname_matches(pname, psref)) {
1641
32.7M
            gs_param_string val;
1642
1643
32.7M
            if (pset->string_defs[i].current != NULL) {
1644
28.0M
                (*pset->string_defs[i].current)(i_ctx_p, &val);
1645
28.0M
                code = param_write_string(plist, pname, &val);
1646
28.0M
                if (code < 0)
1647
0
                    return code;
1648
28.0M
            }
1649
32.7M
        }
1650
52.4M
    }
1651
4.44M
    if (psref) {
1652
        /*
1653
         * Scanner options can be read, but only individually by .getuserparam.
1654
         * This avoids putting them into userparams, and being affected by save/restore.
1655
         */
1656
1.76M
        const char *pname;
1657
1.76M
        bool val;
1658
1.76M
        int code;
1659
1660
1.76M
        switch (ztoken_get_scanner_option(psref, i_ctx_p->scanner_options, &pname)) {
1661
0
            case 0:
1662
0
                code = param_write_null(plist, pname);
1663
0
                break;
1664
0
            case 1:
1665
0
                val = true;
1666
0
                code = param_write_bool(plist, pname, &val);
1667
0
                break;
1668
1.76M
            default:
1669
1.76M
                code = 0;
1670
1.76M
                break;
1671
1.76M
        }
1672
1.76M
        if (code < 0)
1673
0
            return code;
1674
1.76M
    }
1675
4.44M
    return code;
1676
4.44M
}
1677
1678
/* Get the current values of a parameter set to the stack. */
1679
static int
1680
currentparams(i_ctx_t *i_ctx_p, const param_set * pset)
1681
2.67M
{
1682
2.67M
    return current_param_list(i_ctx_p, pset, NULL);
1683
2.67M
}
1684
1685
/* Get the value of a single parameter to the stack, or signal an error. */
1686
static int
1687
currentparam1(i_ctx_t *i_ctx_p, const param_set * pset)
1688
1.76M
{
1689
1.76M
    os_ptr op = osp;
1690
1.76M
    ref sref;
1691
1.76M
    int code;
1692
1693
1.76M
    check_type(*op, t_name);
1694
1.76M
    check_ostack(2);
1695
1.76M
    name_string_ref(imemory, (const ref *)op, &sref);
1696
1.76M
    code = current_param_list(i_ctx_p, pset, &sref);
1697
1.76M
    if (code < 0)
1698
0
        return code;
1699
1.76M
    if (osp == op)
1700
0
        return_error(gs_error_undefined);
1701
    /* We know osp == op + 2. */
1702
1.76M
    ref_assign(op, op + 2);
1703
1.76M
    pop(2);
1704
1.76M
    return code;
1705
1.76M
}