Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/base/gscparam.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 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
/* Default implementation of parameter lists */
18
#include "memory_.h"
19
#include "string_.h"
20
#include "gx.h"
21
#include "gserrors.h"
22
#include "gsparam.h"
23
#include "gsstruct.h"
24
25
/* Forward references */
26
typedef union c_param_value_s {
27
    GS_PARAM_VALUE_UNION(gs_c_param_list);
28
} gs_c_param_value;
29
/*typedef struct gs_c_param_s gs_c_param; *//* in gsparam.h */
30
31
/* Define the GC type for a parameter list. */
32
private_st_c_param_list();
33
34
/* Lengths corresponding to various gs_param_type_xxx types */
35
const byte gs_param_type_sizes[] = {
36
    GS_PARAM_TYPE_SIZES(sizeof(gs_c_param_list))
37
};
38
39
/* Lengths of *actual* data-containing type pointed to or contained by gs_param_type_xxx's */
40
const byte gs_param_type_base_sizes[] = {
41
    GS_PARAM_TYPE_BASE_SIZES(0)
42
};
43
44
/*
45
 * Define a parameter list element.  We use gs_param_type_any to identify
46
 * elements that have been requested but not yet written.  The reading
47
 * procedures must recognize such elements as undefined, and ignore them.
48
 */
49
struct gs_c_param_s {
50
    gs_c_param *next;
51
    gs_param_key_t key;
52
    bool free_key;
53
    gs_c_param_value value;
54
    gs_param_type type;
55
    void *alternate_typed_data;
56
    int error;
57
};
58
59
/* GC descriptor and procedures */
60
gs_private_st_composite(st_c_param, gs_c_param, "gs_c_param",
61
                        c_param_enum_ptrs, c_param_reloc_ptrs);
62
29.3M
ENUM_PTRS_WITH(c_param_enum_ptrs, gs_c_param *param) {
63
11.7M
    index -= 3;
64
11.7M
    switch (param->type) {
65
        /* Only the aggregate types are handled specially. */
66
0
    case gs_param_type_dict:
67
0
    case gs_param_type_dict_int_keys:
68
0
    case gs_param_type_array:
69
0
        return ENUM_USING(st_c_param_list, &param->value.d,
70
0
                          sizeof(param->value.d), index);
71
11.7M
    default: {
72
11.7M
        gs_param_typed_value value;
73
74
11.7M
        value.value = *(const gs_param_value *)&param->value;
75
11.7M
        value.type = param->type;
76
11.7M
        return gs_param_typed_value_enum_ptrs(mem, &value, sizeof(value), index,
77
11.7M
                                              pep, NULL, gcst);
78
0
    }
79
11.7M
    }
80
11.7M
}
81
5.87M
case 0: return ENUM_OBJ(param->next);
82
5.87M
case 1: return ENUM_OBJ(param->alternate_typed_data);
83
5.87M
case 2:
84
5.87M
    if (!param->key.persistent) {
85
5.87M
        gs_const_string key;
86
87
5.87M
        key.data = param->key.data;
88
5.87M
        key.size = param->key.size;
89
5.87M
        return ENUM_STRING(&key);
90
5.87M
    } else
91
0
        return ENUM_OBJ(0);  /* keep going */
92
29.3M
ENUM_PTRS_END
93
5.87M
RELOC_PTRS_WITH(c_param_reloc_ptrs, gs_c_param *param) {
94
5.87M
    RELOC_VAR(param->next);
95
5.87M
    RELOC_VAR(param->alternate_typed_data);
96
5.87M
    if (!param->key.persistent) {
97
5.87M
        gs_const_string key;
98
99
5.87M
        key.data = param->key.data;
100
5.87M
        key.size = param->key.size;
101
5.87M
        RELOC_CONST_STRING_VAR(key);
102
5.87M
        param->key.data = key.data;
103
5.87M
    }
104
5.87M
    switch (param->type) {
105
        /* Only the aggregate types are handled specially. */
106
0
    case gs_param_type_dict:
107
0
    case gs_param_type_dict_int_keys:
108
0
    case gs_param_type_array:
109
0
        RELOC_USING(st_c_param_list, &param->value.d, sizeof(param->value.d));
110
0
        break;
111
5.87M
    default: {
112
5.87M
        gs_param_typed_value value;
113
114
5.87M
        value.value = *(gs_param_value *)&param->value;
115
5.87M
        value.type = param->type;
116
5.87M
        gs_param_typed_value_reloc_ptrs(&value, sizeof(value), NULL, gcst);
117
5.87M
        *(gs_param_value *)&param->value = value.value;
118
5.87M
    }
119
5.87M
    }
120
5.87M
}
121
5.87M
RELOC_PTRS_END
122
123
/* ---------------- Utilities ---------------- */
124
125
gs_c_param_list *
126
gs_c_param_list_alloc(gs_memory_t *mem, client_name_t cname)
127
920k
{
128
920k
    return gs_alloc_struct(mem, gs_c_param_list, &st_c_param_list, cname);
129
920k
}
130
131
void gs_c_param_list_free(gs_memory_t *mem, gs_c_param_list *plist, client_name_t cname)
132
0
{
133
0
    if (plist == NULL)
134
0
        return;
135
0
    gs_c_param_list_release(plist);
136
0
    gs_free_object(mem, plist, cname);
137
0
}
138
139
static gs_c_param *
140
c_param_find(const gs_c_param_list *plist, gs_param_name pkey, bool any)
141
15.7M
{
142
15.7M
    gs_c_param *pparam = plist->head;
143
15.7M
    uint len = strlen(pkey);
144
145
41.0M
    for (; pparam != 0; pparam = pparam->next)
146
40.9M
        if (pparam->key.size == len && !memcmp(pparam->key.data, pkey, len))
147
15.5M
            return (pparam->type != gs_param_type_any || any ? pparam : 0);
148
165k
    return 0;
149
15.7M
}
150
151
/* ---------------- Writing parameters to a list ---------------- */
152
153
static param_proc_begin_xmit_collection(c_param_begin_write_collection);
154
static param_proc_end_xmit_collection(c_param_end_write_collection);
155
static param_proc_xmit_typed(c_param_write_typed);
156
static param_proc_request(c_param_request);
157
static param_proc_requested(c_param_requested);
158
static const gs_param_list_procs c_write_procs =
159
{
160
    c_param_write_typed,
161
    c_param_begin_write_collection,
162
    c_param_end_write_collection,
163
    NULL,     /* get_next_key */
164
    c_param_request,
165
    c_param_requested
166
};
167
168
/* Initialize a list for writing. */
169
void
170
gs_c_param_list_write(gs_c_param_list * plist, gs_memory_t * mem)
171
2.01M
{
172
2.01M
    plist->memory = mem;
173
2.01M
    plist->head = 0;
174
2.01M
    plist->target = 0;    /* not used for writing */
175
2.01M
    plist->count = 0;
176
2.01M
    plist->any_requested = false;
177
2.01M
    plist->persistent_keys = true;
178
2.01M
    gs_c_param_list_write_more(plist);
179
2.01M
}
180
181
/* Set the target of a list.  Only relevant for reading. */
182
void
183
gs_c_param_list_set_target(gs_c_param_list *plist, gs_param_list *target)
184
6.15k
{
185
6.15k
    plist->target = target;
186
6.15k
}
187
188
/* Re-enable a list for writing, without clearing it. */
189
/* gs_c_param_list_write must have been called previously. */
190
void
191
gs_c_param_list_write_more(gs_c_param_list * plist)
192
2.04M
{
193
2.04M
    plist->procs = &c_write_procs;
194
2.04M
    plist->coll_type = gs_param_collection_dict_any;
195
2.04M
}
196
197
/* Release a list. */
198
void
199
gs_c_param_list_release(gs_c_param_list * plist)
200
1.36M
{
201
1.36M
    gs_memory_t *mem = plist->memory;
202
1.36M
    gs_c_param *pparam;
203
204
2.07M
    while ((pparam = plist->head) != 0) {
205
704k
        gs_c_param *next = pparam->next;
206
207
704k
        switch (pparam->type) {
208
0
            case gs_param_type_dict:
209
0
            case gs_param_type_dict_int_keys:
210
0
            case gs_param_type_array:
211
0
                gs_c_param_list_release(&pparam->value.d);
212
0
                break;
213
209
            case gs_param_type_string:
214
209
            case gs_param_type_name:
215
179k
            case gs_param_type_int_array:
216
179k
            case gs_param_type_float_array:
217
208k
            case gs_param_type_string_array:
218
208k
            case gs_param_type_name_array:
219
208k
                if (!pparam->value.s.persistent)
220
208k
                    gs_free_const_object(mem, pparam->value.s.data,
221
208k
                                         "gs_c_param_list_release data");
222
208k
                break;
223
496k
            default:
224
496k
                break;
225
704k
        }
226
704k
        if (pparam->free_key) {
227
            /* We allocated this, so we must free it. */
228
442k
            gs_free_const_string(mem, pparam->key.data, pparam->key.size,
229
442k
                                 "gs_c_param_list_release key");
230
442k
        }
231
704k
        gs_free_object(mem, pparam->alternate_typed_data,
232
704k
                       "gs_c_param_list_release alternate data");
233
704k
        gs_free_object(mem, pparam,
234
704k
                       "gs_c_param_list_release entry");
235
704k
        plist->head = next;
236
704k
        plist->count--;
237
704k
    }
238
1.36M
}
239
240
/* Add an entry to a list.  Doesn't set: value, type, plist->head. */
241
static gs_c_param *
242
c_param_add(gs_c_param_list * plist, gs_param_name pkey)
243
3.51M
{
244
3.51M
    gs_c_param *pparam =
245
3.51M
        gs_alloc_struct(plist->memory, gs_c_param, &st_c_param,
246
3.51M
                        "c_param_add entry");
247
3.51M
    uint len;
248
249
3.51M
    if ((pparam == NULL) || (pkey == NULL))
250
0
        return NULL;
251
252
3.51M
    len = strlen(pkey);
253
3.51M
    pparam->next = plist->head;
254
3.51M
    if (!plist->persistent_keys) {
255
        /* We must copy the key. */
256
3.25M
        byte *str = gs_alloc_string(plist->memory, len, "c_param_add key");
257
258
3.25M
        if (str == 0) {
259
0
            gs_free_object(plist->memory, pparam, "c_param_add entry");
260
0
            return 0;
261
0
        }
262
3.25M
        memcpy(str, pkey, len);
263
3.25M
        pparam->key.data = str;
264
3.25M
        pparam->key.persistent = false; /* we will free it */
265
3.25M
        pparam->free_key = true;
266
3.25M
    } else {
267
261k
        pparam->key.data = (const byte *)pkey;
268
261k
        pparam->key.persistent = true;
269
261k
        pparam->free_key = false;
270
261k
    }
271
3.51M
    pparam->key.size = len;
272
3.51M
    pparam->alternate_typed_data = 0;
273
3.51M
    pparam->error = 0;
274
3.51M
    return pparam;
275
3.51M
}
276
277
/*  Write a dynamically typed parameter to a list. */
278
static int
279
c_param_write(gs_c_param_list * plist, gs_param_name pkey, void *pvalue,
280
              gs_param_type type)
281
3.51M
{
282
3.51M
    unsigned top_level_sizeof = 0;
283
3.51M
    unsigned second_level_sizeof = 0;
284
3.51M
    gs_c_param *pparam = c_param_add(plist, pkey);
285
286
3.51M
    if (pparam == 0)
287
0
        return_error(gs_error_VMerror);
288
3.51M
    memcpy(&pparam->value, pvalue, gs_param_type_sizes[(int)type]);
289
3.51M
    pparam->type = type;
290
291
    /* Need deeper copies of data if it's not persistent */
292
3.51M
    switch (type) {
293
0
            gs_param_string const *curr_string;
294
0
            gs_param_string const *end_string;
295
296
28.9k
        case gs_param_type_string_array:
297
28.9k
        case gs_param_type_name_array:
298
            /* Determine how much mem needed to hold actual string data */
299
28.9k
            curr_string = pparam->value.sa.data;
300
28.9k
            end_string = curr_string + pparam->value.sa.size;
301
134k
            for (; curr_string < end_string; ++curr_string)
302
105k
                if (!curr_string->persistent)
303
105k
                    second_level_sizeof += curr_string->size;
304
            /* fall thru */
305
306
29.1k
        case gs_param_type_string:
307
29.1k
        case gs_param_type_name:
308
1.50M
        case gs_param_type_int_array:
309
1.50M
        case gs_param_type_float_array:
310
1.50M
            if (!pparam->value.s.persistent) { /* Allocate & copy object pointed to by array or string */
311
1.50M
                byte *top_level_memory = NULL;
312
313
1.50M
                top_level_sizeof =
314
1.50M
                    pparam->value.s.size * gs_param_type_base_sizes[type];
315
1.50M
                if (top_level_sizeof + second_level_sizeof > 0) {
316
1.50M
                    top_level_memory =
317
1.50M
                        gs_alloc_bytes_immovable(plist->memory,
318
1.50M
                                     top_level_sizeof + second_level_sizeof,
319
1.50M
                                             "c_param_write data");
320
1.50M
                    if (top_level_memory == 0) {
321
0
                        if (pparam->key.persistent == false) {
322
0
                            gs_free_string(plist->memory, (byte *)(pparam->key.data),
323
0
                                strlen((const char *)(pparam->key.data)), "c_param_add key");
324
0
                        }
325
0
                        gs_free_object(plist->memory, pparam, "c_param_write entry");
326
0
                        return_error(gs_error_VMerror);
327
0
                    }
328
1.50M
                    memcpy(top_level_memory, pparam->value.s.data, top_level_sizeof);
329
1.50M
                }
330
1.50M
                pparam->value.s.data = top_level_memory;
331
332
                /* String/name arrays need to copy actual str data */
333
334
1.50M
                if (second_level_sizeof > 0) {
335
28.9k
                    byte *second_level_memory =
336
28.9k
                    top_level_memory + top_level_sizeof;
337
338
28.9k
                    curr_string = pparam->value.sa.data;
339
28.9k
                    end_string = curr_string + pparam->value.sa.size;
340
134k
                    for (; curr_string < end_string; ++curr_string)
341
105k
                        if (!curr_string->persistent) {
342
105k
                            memcpy(second_level_memory,
343
105k
                                   curr_string->data, curr_string->size);
344
105k
                            ((gs_param_string *) curr_string)->data
345
105k
                                = second_level_memory;
346
105k
                            second_level_memory += curr_string->size;
347
105k
                        }
348
28.9k
                }
349
1.50M
            }
350
1.50M
            break;
351
2.00M
        default:
352
2.00M
            break;
353
3.51M
    }
354
355
3.51M
    plist->head = pparam;
356
3.51M
    plist->count++;
357
3.51M
    return 0;
358
3.51M
}
359
360
/* Individual writing routines. */
361
static int
362
c_param_begin_write_collection(gs_param_list * plist, gs_param_name pkey,
363
               gs_param_dict * pvalue, gs_param_collection_type_t coll_type)
364
0
{
365
0
    gs_c_param_list *const cplist = (gs_c_param_list *)plist;
366
0
    gs_c_param_list *dlist =
367
0
        gs_c_param_list_alloc(cplist->memory,
368
0
                              "c_param_begin_write_collection");
369
370
0
    if (dlist == 0)
371
0
        return_error(gs_error_VMerror);
372
0
    gs_c_param_list_write(dlist, cplist->memory);
373
0
    dlist->coll_type = coll_type;
374
0
    pvalue->list = (gs_param_list *) dlist;
375
0
    return 0;
376
0
}
377
static int
378
c_param_end_write_collection(gs_param_list * plist, gs_param_name pkey,
379
                             gs_param_dict * pvalue)
380
0
{
381
0
    gs_c_param_list *const cplist = (gs_c_param_list *)plist;
382
0
    gs_c_param_list *dlist = (gs_c_param_list *) pvalue->list;
383
0
    int code;
384
385
0
    code = c_param_write(cplist, pkey, pvalue->list,
386
0
                    (dlist->coll_type == gs_param_collection_dict_int_keys ?
387
0
                     gs_param_type_dict_int_keys :
388
0
                     dlist->coll_type == gs_param_collection_array ?
389
0
                     gs_param_type_array : gs_param_type_dict));
390
391
0
    gs_free_object(plist->memory, pvalue->list, "c_param_end_write_collection");
392
0
    pvalue->list = 0;
393
0
    return code;
394
0
}
395
static int
396
c_param_write_typed(gs_param_list * plist, gs_param_name pkey,
397
                    gs_param_typed_value * pvalue)
398
3.51M
{
399
3.51M
    gs_c_param_list *const cplist = (gs_c_param_list *)plist;
400
3.51M
    gs_param_collection_type_t coll_type;
401
402
3.51M
    switch (pvalue->type) {
403
0
        case gs_param_type_dict:
404
0
            coll_type = gs_param_collection_dict_any;
405
0
            break;
406
0
        case gs_param_type_dict_int_keys:
407
0
            coll_type = gs_param_collection_dict_int_keys;
408
0
            break;
409
0
        case gs_param_type_array:
410
0
            coll_type = gs_param_collection_array;
411
0
            break;
412
3.51M
        default:
413
3.51M
            return c_param_write(cplist, pkey, &pvalue->value, pvalue->type);
414
3.51M
    }
415
0
    return c_param_begin_write_collection
416
0
        (plist, pkey, &pvalue->value.d, coll_type);
417
3.51M
}
418
419
/* Other procedures */
420
421
static int
422
c_param_request(gs_param_list * plist, gs_param_name pkey)
423
0
{
424
0
    gs_c_param_list *const cplist = (gs_c_param_list *)plist;
425
0
    gs_c_param *pparam;
426
427
0
    cplist->any_requested = true;
428
0
    if (c_param_find(cplist, pkey, true))
429
0
        return 0;
430
0
    pparam = c_param_add(cplist, pkey);
431
0
    if (pparam == 0)
432
0
        return_error(gs_error_VMerror);
433
0
    pparam->type = gs_param_type_any; /* mark as undefined */
434
0
    cplist->head = pparam;
435
0
    return 0;
436
0
}
437
438
static int
439
c_param_requested(const gs_param_list * plist, gs_param_name pkey)
440
0
{
441
0
    const gs_c_param_list *const cplist = (const gs_c_param_list *)plist;
442
0
    gs_param_list *target = cplist->target;
443
0
    int code;
444
445
0
    if (!cplist->any_requested)
446
0
        return (target ? param_requested(target, pkey) : -1);
447
0
    if (c_param_find(cplist, pkey, true) != 0)
448
0
        return 1;
449
0
    if (!target)
450
0
        return 0;
451
0
    code = param_requested(target, pkey);
452
0
    return (code < 0 ? 0 : 1);
453
0
}
454
455
/* ---------------- Reading from a list to parameters ---------------- */
456
457
static param_proc_begin_xmit_collection(c_param_begin_read_collection);
458
static param_proc_end_xmit_collection(c_param_end_read_collection);
459
static param_proc_xmit_typed(c_param_read_typed);
460
static param_proc_next_key(c_param_get_next_key);
461
static param_proc_get_policy(c_param_read_get_policy);
462
static param_proc_signal_error(c_param_read_signal_error);
463
static param_proc_read_signalled_error(c_param_read_signalled_error);
464
static param_proc_commit(c_param_read_commit);
465
static const gs_param_list_procs c_read_procs =
466
{
467
    c_param_read_typed,
468
    c_param_begin_read_collection,
469
    c_param_end_read_collection,
470
    c_param_get_next_key,
471
    NULL,     /* request, N/A */
472
    NULL,     /* requested, N/A */
473
    c_param_read_get_policy,
474
    c_param_read_signal_error,
475
    c_param_read_commit,
476
    c_param_read_signalled_error
477
};
478
479
/* Switch a list from writing to reading. */
480
void
481
gs_c_param_list_read(gs_c_param_list * plist)
482
4.43M
{
483
4.43M
    plist->procs = &c_read_procs;
484
4.43M
}
485
486
/* Generic routine for reading a parameter from a list. */
487
488
static int
489
c_param_read_typed(gs_param_list * plist, gs_param_name pkey,
490
                   gs_param_typed_value * pvalue)
491
15.7M
{
492
15.7M
    gs_c_param_list *const cplist = (gs_c_param_list *)plist;
493
15.7M
    gs_param_type req_type = pvalue->type;
494
15.7M
    gs_c_param *pparam = c_param_find(cplist, pkey, false);
495
15.7M
    int code;
496
497
15.7M
    if (pparam == 0)
498
140k
        return (cplist->target ?
499
79.9k
                param_read_typed(cplist->target, pkey, pvalue) : 1);
500
15.5M
    pvalue->type = pparam->type;
501
15.5M
    switch (pvalue->type) {
502
0
        case gs_param_type_dict:
503
0
        case gs_param_type_dict_int_keys:
504
0
        case gs_param_type_array:
505
0
            gs_c_param_list_read(&pparam->value.d);
506
0
            pvalue->value.d.list = (gs_param_list *) & pparam->value.d;
507
0
            pvalue->value.d.size = pparam->value.d.count;
508
0
            return 0;
509
15.5M
        default:
510
15.5M
            break;
511
15.5M
    }
512
15.5M
    memcpy(&pvalue->value, &pparam->value,
513
15.5M
           gs_param_type_sizes[(int)pparam->type]);
514
15.5M
    code = param_coerce_typed(pvalue, req_type, NULL);
515
/****** SHOULD LET param_coerce_typed DO THIS ******/
516
15.5M
    if (code == gs_error_typecheck &&
517
15.5M
        req_type == gs_param_type_float_array &&
518
15.5M
        pvalue->type == gs_param_type_int_array
519
15.5M
        ) {
520
        /* Convert int array to float dest */
521
0
        gs_param_float_array fa;
522
0
        int element;
523
524
0
        fa.size = pparam->value.ia.size;
525
0
        fa.persistent = false;
526
527
0
        if (pparam->alternate_typed_data == 0) {
528
0
            if ((pparam->alternate_typed_data
529
0
                 = (void *)gs_alloc_bytes_immovable(cplist->memory,
530
0
                                                    fa.size * sizeof(float),
531
0
                             "gs_c_param_read alternate float array")) == 0)
532
0
                      return_error(gs_error_VMerror);
533
534
0
            for (element = 0; element < fa.size; ++element)
535
0
                ((float *)(pparam->alternate_typed_data))[element]
536
0
                    = (float)pparam->value.ia.data[element];
537
0
        }
538
0
        fa.data = (float *)pparam->alternate_typed_data;
539
540
0
        pvalue->value.fa = fa;
541
0
        pvalue->type = req_type;
542
0
        return 0;
543
0
    }
544
15.5M
    return code;
545
15.5M
}
546
547
/* Individual reading routines. */
548
static int
549
c_param_begin_read_collection(gs_param_list * plist, gs_param_name pkey,
550
               gs_param_dict * pvalue, gs_param_collection_type_t coll_type)
551
24.6k
{
552
24.6k
    gs_c_param_list *const cplist = (gs_c_param_list *)plist;
553
24.6k
    gs_c_param *pparam = c_param_find(cplist, pkey, false);
554
555
24.6k
    if (pparam == 0)
556
24.6k
        return
557
24.6k
            (cplist->target ?
558
12.3k
             param_begin_read_collection(cplist->target,
559
24.6k
                                         pkey, pvalue, coll_type) :
560
24.6k
             1);
561
0
    switch (pparam->type) {
562
0
        case gs_param_type_dict:
563
0
            if (coll_type != gs_param_collection_dict_any)
564
0
                return_error(gs_error_typecheck);
565
0
            break;
566
0
        case gs_param_type_dict_int_keys:
567
0
            if (coll_type == gs_param_collection_array)
568
0
                return_error(gs_error_typecheck);
569
0
            break;
570
0
        case gs_param_type_array:
571
0
            break;
572
0
        default:
573
0
            return_error(gs_error_typecheck);
574
0
    }
575
0
    gs_c_param_list_read(&pparam->value.d);
576
0
    pvalue->list = (gs_param_list *) & pparam->value.d;
577
0
    pvalue->size = pparam->value.d.count;
578
0
    return 0;
579
0
}
580
static int
581
c_param_end_read_collection(gs_param_list * plist, gs_param_name pkey,
582
                            gs_param_dict * pvalue)
583
0
{
584
0
    return 0;
585
0
}
586
587
/* Other procedures */
588
static int      /* ret 0 ok, 1 if EOF, or -ve err */
589
c_param_get_next_key(gs_param_list * plist, gs_param_enumerator_t * penum,
590
                     gs_param_key_t * key)
591
19.3M
{
592
19.3M
    gs_c_param_list *const cplist = (gs_c_param_list *)plist;
593
19.3M
    gs_c_param *pparam =
594
19.3M
    (penum->pvoid ? ((gs_c_param *) (penum->pvoid))->next :
595
19.3M
     cplist->head);
596
597
19.3M
    if (pparam == 0)
598
4.12M
        return 1;
599
15.2M
    penum->pvoid = pparam;
600
15.2M
    *key = pparam->key;
601
15.2M
    return 0;
602
19.3M
}
603
static int
604
c_param_read_get_policy(gs_param_list * plist, gs_param_name pkey)
605
0
{
606
0
    return gs_param_policy_ignore;
607
0
}
608
static int
609
c_param_read_signal_error(gs_param_list * plist, gs_param_name pkey, int code)
610
5
{
611
5
    gs_c_param_list *const cplist = (gs_c_param_list *)plist;
612
5
    gs_c_param *pparam = c_param_find(cplist, pkey, false);
613
614
5
    if (pparam)
615
5
        pparam->error = code;
616
617
5
    return 0;
618
5
}
619
static int
620
c_param_read_commit(gs_param_list * plist)
621
0
{
622
0
    return 0;
623
0
}
624
static int
625
c_param_read_signalled_error(gs_param_list * plist, gs_param_name pkey)
626
0
{
627
0
    gs_c_param_list *const cplist = (gs_c_param_list *)plist;
628
0
    gs_c_param *pparam = c_param_find(cplist, pkey, false);
629
630
0
    return (pparam ? pparam->error : 0);
631
0
}